companion-shell-integration.test.mjs
124 lines 4.1 KB
Raw
sha256:65ccb454656ea5acdea0a10e559b78bcde1eb6ff753ecc2911bc99d1c3d7cadd feat(calendar): enforce agent context tiers in retrieval AP… Human minor ⚠ breaking 1 day ago
1 /**
2 * Tier 2 — INTEGRATION: Phase 5 adapters composed with Phase 2–4 cores.
3 */
4
5 import { after, describe, it } from 'node:test';
6 import assert from 'node:assert/strict';
7 import crypto from 'node:crypto';
8 import { mkdtemp, readFile, rm } from 'node:fs/promises';
9 import os from 'node:os';
10 import path from 'node:path';
11
12 import { createCompanionInferenceListener } from '../lib/companion-inference-listener.mjs';
13 import {
14 createCompanionShell,
15 createRuntimeGroup,
16 downloadVerifyAndStageModel,
17 } from '../lib/companion-shell.mjs';
18
19 const tmpRoots = [];
20 after(async () => {
21 for (const dir of tmpRoots) await rm(dir, { recursive: true, force: true });
22 });
23
24 function sha256(data) {
25 return crypto.createHash('sha256').update(data).digest('hex');
26 }
27
28 describe('guarded listener fronts the runtime callback', () => {
29 it('admits only same-origin loopback requests with the bearer token', async () => {
30 let runtimeHits = 0;
31 const listener = createCompanionInferenceListener({
32 expectedToken: 'loopback-token',
33 runtimeRequest(_req, res) {
34 runtimeHits += 1;
35 res.statusCode = 200;
36 res.setHeader('Content-Type', 'application/json');
37 res.end(JSON.stringify({ ok: true }));
38 },
39 });
40 const bound = await listener.start();
41 try {
42 const url = `http://127.0.0.1:${bound.port}/v1/models`;
43 const denied = await fetch(url, { headers: { Origin: 'https://evil.example', Authorization: 'Bearer loopback-token' } });
44 assert.equal(denied.status, 403);
45 assert.equal(runtimeHits, 0);
46
47 const allowed = await fetch(url, {
48 headers: {
49 Host: `127.0.0.1:${bound.port}`,
50 Origin: `http://127.0.0.1:${bound.port}`,
51 'Sec-Fetch-Site': 'same-origin',
52 Authorization: 'Bearer loopback-token',
53 },
54 });
55 assert.equal(allowed.status, 200);
56 assert.equal(runtimeHits, 1);
57 assert.equal(allowed.headers.get('access-control-allow-origin'), null);
58 } finally {
59 await listener.close();
60 }
61 });
62 });
63
64 describe('download → integrity → atomic stage', () => {
65 it('streams chunks through the accumulator before verified rename', async () => {
66 const data = Buffer.from('verified model payload');
67 const dir = await mkdtemp(path.join(os.tmpdir(), 'knowtation-phase5-'));
68 tmpRoots.push(dir);
69 const tempPath = path.join(dir, 'model.tmp');
70 const verifiedPath = path.join(dir, 'model.gguf');
71 const runtimeGroup = createRuntimeGroup({
72 spawn: async () => ({ pid: 42, kill: async () => {} }),
73 healthCheck: async () => true,
74 async download(_url, onChunk) {
75 onChunk(data.subarray(0, 8));
76 onChunk(data.subarray(8));
77 },
78 });
79
80 const result = await downloadVerifyAndStageModel({
81 runtimeGroup,
82 tempPath,
83 verifiedPath,
84 spec: {
85 modelUrl: 'https://cdn.knowtation-models.com/model.gguf',
86 expectedDigest: sha256(data),
87 expectedSizeBytes: data.length,
88 allowedSourceUrls: ['https://cdn.knowtation-models.com/'],
89 },
90 });
91
92 assert.equal(result.verifiedPath, verifiedPath);
93 assert.equal(await readFile(verifiedPath, 'utf8'), data.toString('utf8'));
94 });
95 });
96
97 describe('runtime lifecycle drives lane selection', () => {
98 it('integrity + listener + token + health_ok flips companionAvailable and selects local', async () => {
99 let now = 1000;
100 const shell = createCompanionShell({
101 now: () => now,
102 healthRecencyMs: 500,
103 runtimeGroup: {
104 spawn: async () => ({ pid: 7, port: 41111, kill: async () => {} }),
105 download: async () => {},
106 healthCheck: async () => true,
107 },
108 });
109 shell.markIntegrityVerified();
110 shell.setListenerBound(true);
111 shell.setLoopbackTokenPresent(true);
112 await shell.startRuntime({
113 binaryPath: '/opt/knowtation/runtime',
114 modelPath: '/models/verified.gguf',
115 port: 41111,
116 maxRamBytes: 1024,
117 });
118
119 assert.equal(shell.companionAvailable(), true);
120 assert.equal(shell.selectLane({}, { managedKeyAvailable: true }), 'local');
121 now = 2000;
122 assert.equal(shell.companionAvailable(), false);
123 });
124 });
File History 2 commits
sha256:65ccb454656ea5acdea0a10e559b78bcde1eb6ff753ecc2911bc99d1c3d7cadd feat(calendar): enforce agent context tiers in retrieval AP… Human minor 1 day ago
sha256:9103f98c89257ed2b01c237cea895dabb3e85ea337dccb1161c175e4422355b6 docs: accept Calendar Events v0 spec with Phase 0 security … Human 1 day ago