This commit is contained in:
2026-09-11 14:35:22 -04:00
parent aba185d80a
commit cc182f2ef1
10 changed files with 86 additions and 17 deletions
+24
View File
@@ -6,6 +6,11 @@ import path from 'node:path';
import net from 'node:net';
import { PrivacyLog } from '../daemon/privacy-log.js';
import { createEventSocket, sendEvent } from '../daemon/ipc.js';
import { StateRecovery } from '../daemon/recovery.js';
import { runIsolatedJob } from '../daemon/job-runner.js';
import { QvacScheduler } from '../daemon/qvac-scheduler.js';
import { ComputerAudit } from '../computer-use/audit.js';
import { writeFile } from 'node:fs/promises';
test('privacy log allowlists metadata and excludes prompt contents', async () => {
const dir = await mkdtemp(path.join(tmpdir(), 'jarvis-log-'));
@@ -36,3 +41,22 @@ test('event socket rejects bulk messages and transports small JSON events', asyn
assert.deepEqual(received, [{ event: 'Token', text: 'hello' }]);
await ipc.close();
});
test('failed background jobs stay isolated and scheduler remains usable', async () => {
const scheduler = new QvacScheduler(); const errors = [];
const failed = await runIsolatedJob(scheduler, async () => { throw new Error('OOM'); }, { onError: (e) => errors.push(e.message) });
assert.deepEqual(failed, { ok: false, unavailable: 'OOM', isolated: true });
assert.deepEqual(await scheduler.run(async () => 'voice', { lane: 'voice' }), 'voice');
assert.deepEqual(errors, ['OOM']); assert.equal(scheduler.metrics().failed, 1);
});
test('state recovery is atomic and safe after an interrupted turn', async () => {
const dir = await mkdtemp(path.join(tmpdir(), 'jarvis-recovery-')); const recovery = new StateRecovery({ file: path.join(dir, 'state.json') });
recovery.save({ state: 'THINKING', mode: 'chat' }); assert.deepEqual(recovery.load(), { state: 'ARMED', mode: 'chat', recovered: true });
});
test('computer audit stores hashes and never stores screenshot bytes', async () => {
const dir = await mkdtemp(path.join(tmpdir(), 'jarvis-audit-')); const frame = path.join(dir, 'frame.png'); await writeFile(frame, 'private pixels'); const audit = new ComputerAudit({ dir });
const row = await audit.record('observe', { name: 'Window', role: 'window' }, { ok: true, screenshotPath: frame }); const text = await readFile(path.join(dir, `cu-${new Date().toISOString().slice(0, 10).replaceAll('-', '')}.jsonl`), 'utf8');
assert.equal(row.screenshot_hash.length, 64); assert.doesNotMatch(text, /private pixels/); assert.doesNotMatch(text, /frame\.png/);
});