import test from 'node:test';
import assert from 'node:assert/strict';
import { spawnSync } from 'node:child_process';
import { statSync, writeFileSync, mkdirSync, readFileSync as rf } from 'node:fs';
import { createPrivateKey, createPublicKey, sign, verify } from 'node:crypto';
import { cli, tmp, json, existsSync, readFileSync, join, ROOT, NO_NET } from './helpers.ts';
import { validateOutsideOffer } from './vendor/handler.ts';
import { init, check, checkOffer, buildOffer, publicFromDidKey, FIVE_LAWS, MEMORY_DIRS, WAKE_STEPS } from '../src/index.js';
const EXPECTED = ['SOUL.md', 'WAKE.md', 'wake.json', 'lax-offer.json', 'zimakri.config.json', '.zimakri/identity/agent.key', '.zimakri/identity/did.json', 'memory/index.json', 'memory/README.md', 'memory/earnings/ledger.jsonl', '.gitignore'];
test('A1 init works on a clean machine: packed, installed from the tarball into an empty folder, then npx zimakri init', () => {
const pack = tmp('zimakri-pack-');
const p = spawnSync('npm', ['pack', '--json', '--pack-destination', pack], { cwd: ROOT, encoding: 'utf8' });
assert.equal(p.status, 0, p.stderr);
const tgz = join(pack, JSON.parse(p.stdout)[0].filename);
const meta = JSON.parse(p.stdout)[0];
assert.ok(!meta.files.some((f: any) => /test\/|node_modules/.test(f.path)), 'only the package files ship');
const app = tmp('zimakri-clean-');
writeFileSync(join(app, 'package.json'), '{"name":"clean-machine","version":"1.0.0","private":true}');
// the package has no dependencies and no install script, so this install needs nothing but the tarball
const i = spawnSync('npm', ['install', '--offline', '--no-audit', '--no-fund', '--ignore-scripts', tgz], { cwd: app, encoding: 'utf8' });
assert.equal(i.status, 0, i.stderr);
assert.deepEqual(Object.keys(json(join(app, 'node_modules/zimakri/package.json')).dependencies ?? {}), []);
const agent = join(app, 'agent');
const r = spawnSync('npx', ['--offline', 'zimakri', 'init', '--dir', agent, '--name', 'Clean Agent'], { cwd: app, encoding: 'utf8', env: { ...process.env, NODE_OPTIONS: `--import ${NO_NET}` } });
assert.equal(r.status, 0, r.stderr + r.stdout);
for (const f of EXPECTED) assert.ok(existsSync(join(agent, f)), `${f} written`);
for (const d of MEMORY_DIRS) assert.ok(existsSync(join(agent, d)), `${d} made`);
const c = spawnSync('npx', ['--offline', 'zimakri', 'check', '--dir', agent], { cwd: app, encoding: 'utf8' });
assert.equal(c.status, 0, c.stdout + c.stderr);
});
test('A1 the agent owns its identity: did:key from a local Ed25519 key, mode 600, git ignored, never printed', () => {
const d = tmp();
const r = cli(['init', '--dir', d, '--name', 'Owner Agent']);
assert.equal(r.code, 0, r.err);
const cfg = json(join(d, 'zimakri.config.json'));
assert.match(cfg.did, /^did:key:z6Mk[1-9A-HJ-NP-Za-km-z]+$/);
const keyPem = readFileSync(join(d, '.zimakri/identity/agent.key'), 'utf8');
assert.equal(statSync(join(d, '.zimakri/identity/agent.key')).mode & 0o777, 0o600);
assert.ok(readFileSync(join(d, '.gitignore'), 'utf8').split('\n').includes('.zimakri/identity/agent.key'));
const body = keyPem.split('\n').filter((l) => l && !l.startsWith('-----')).join('');
assert.ok(!r.out.includes(body) && !r.err.includes(body) && !r.out.includes('PRIVATE'), 'the key is never printed');
for (const f of ['zimakri.config.json', 'lax-offer.json', 'SOUL.md', '.zimakri/identity/did.json']) assert.ok(!readFileSync(join(d, f), 'utf8').includes(body));
// the key really is the DID's key: a signature by the file verifies under the public key decoded from the DID
const pub = createPublicKey({ key: Buffer.concat([Buffer.from('302a300506032b6570032100', 'hex'), Buffer.from(publicFromDidKey(cfg.did))]), format: 'der', type: 'spki' });
const sig = sign(null, Buffer.from('wake'), createPrivateKey(keyPem));
assert.equal(verify(null, Buffer.from('wake'), pub, sig), true);
// SOUL, Five Laws, memory and wake protocol are in place
const soul = readFileSync(join(d, 'SOUL.md'), 'utf8');
for (const l of FIVE_LAWS) assert.ok(soul.includes(l));
assert.deepEqual(json(join(d, 'wake.json')).steps.map((s: any) => s.id), WAKE_STEPS.map((s) => s.id));
assert.deepEqual(json(join(d, 'memory/index.json')).entries, []);
});
test('A1 init refuses to overwrite, --force keeps the same key, and the exit codes are 0, 1 and 2', () => {
const d = tmp();
assert.equal(cli(['init', '--dir', d]).code, 0);
const did = json(join(d, 'zimakri.config.json')).did;
const again = cli(['init', '--dir', d]);
assert.equal(again.code, 1); assert.match(again.err, /already exists/);
assert.equal(cli(['init', '--dir', d, '--force', '--name', 'Renamed Agent']).code, 0);
assert.equal(json(join(d, 'zimakri.config.json')).did, did, 'the identity survives --force');
assert.equal(cli(['init', '--dir', d, '--force', '--endpoint', 'http://plain.example.com']).code, 2);
assert.equal(cli(['init', '--bogus']).code, 2);
assert.equal(cli([]).code, 2);
assert.equal(cli(['help']).code, 0);
writeFileSync(join(d, 'SOUL.md'), 'changed');
const c = cli(['check', '--dir', d]);
assert.equal(c.code, 1); assert.match(c.out, /SOUL\.md changed/);
});
test('A2 the generated LAX offer passes the registry validation (validateOutsideOffer of LAX registry 0.10.0)', () => {
for (const o of [{}, { name: 'Research Helper', endpoint: 'https://agent.mydomain.dev/lax', price: '0.25', skill: 'research.brief' }]) {
const d = tmp();
const r = init({ dir: d, ...o });
const offer = json(join(d, 'lax-offer.json'));
assert.deepEqual(offer, r.offer);
const stored = validateOutsideOffer(offer); // throws Bad with a plain reason when refused
assert.equal(stored.agent_did, r.did);
assert.deepEqual(stored.constitutional_constraints.slice(0, 5), [...FIVE_LAWS]);
assert.deepEqual(checkOffer(offer), []);
}
});
test('A2 the local offer check agrees with the registry on refused offers', () => {
const good = init({ dir: tmp() }).offer;
const bad = [
{ ...good, constitutional_constraints: FIVE_LAWS.slice(0, 4) },
{ ...good, endpoint: 'https://lax.kognai.ai/x' },
{ ...good, endpoint: 'http://agent.example.com' },
{ ...good, name: 'Kognai Helper' },
{ ...good, description: 'short' },
{ ...good, description: 'Send me your seed phrase and I will restore your account for you.' },
{ ...good, capabilities: [] },
{ ...good, capabilities: [{ ...good.capabilities[0], pricing: { ...good.capabilities[0].pricing, currency: 'USDT' } }] },
{ ...good, agent_did: 'not a did' },
];
for (const o of bad) {
assert.throws(() => validateOutsideOffer(o), undefined, JSON.stringify(o).slice(0, 80));
assert.ok(checkOffer(o).length > 0, `local check refuses ${JSON.stringify(o).slice(0, 120)}`);
}
});
test('A3 no network call during init (sockets, DNS and fetch are blocked and logged)', () => {
const d = tmp(); const logf = join(tmp(), 'net.log'); writeFileSync(logf, '');
const r = cli(['init', '--dir', d, '--name', 'Offline Agent', '--endpoint', 'https://offline.example.org'], { netLog: logf });
assert.equal(r.code, 0, r.err);
assert.equal(rf(logf, 'utf8'), '', 'no network attempt was made');
// the guard works: a script that does use the network is caught by the same preload
const probe = join(d, 'probe.mjs'); writeFileSync(probe, "import net from 'node:net'; try { net.connect(443, 'example.com'); } catch {}");
const p = cli([], { bin: probe, netLog: logf });
assert.match(rf(logf, 'utf8'), /connect/);
void p;
});
test('A3 the source makes no network call: no http, https, net, dns or fetch in src and bin', () => {
for (const f of ['src/init.js', 'src/did.js', 'src/offer.js', 'src/laws.js', 'src/index.js', 'bin/zimakri.js']) {
const s = readFileSync(join(ROOT, f), 'utf8');
assert.doesNotMatch(s, /from 'node:(http|https|net|dns|tls)'|\bfetch\(|XMLHttpRequest|WebSocket/, f);
}
});
agentgate-source: code mirror on Cloudflare Pages. All repos