// P1's human proof boundary; all records and fixture input under short TMPDIR. import test from 'node:test'; import assert from 'node:assert/strict'; import { mkdtempSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { Broker } from '../src/broker.mjs'; import { Store } from '../src/store.mjs'; const role={authority:{withinRole:['message.send'],crossRole:[]}}; function fixture(t,proxyInit){const store=new Store(mkdtempSync(join(tmpdir(),'p1-bus-')));t.after(()=>store.close());const b=new Broker({store,proxyInit,businesses:{demo:{id:'demo',human:'owner',arbiters:{technical:'coder',delivery:'coder'},vars:{'bus.tester':true},roles:{coder:role}}}});return {store,b,human:b.bindHuman({business:'demo',human:'owner',via:'cli',outsideAgent:true}),tester:b.bindTester({business:'demo'}),reader:b.bindReader({business:'demo'}),agent:b.bindLaunch({business:'demo',role:'coder',run:'p1-run',harness:'pi'})};} test('proxy.init only accepts path-bound outside-agent human; refuses agent/tester/reader',async t=>{const calls=[];const f=fixture(t,async a=>{calls.push(a);return {port:a.port,binary:'/fixture'};});for(const cap of [f.tester,f.agent])assert.throws(()=>f.b.request(cap,{verb:'proxy.init',args:{key:'p1-management'}}),e=>e.code==='human-required');assert.throws(()=>f.b.request(f.reader,{verb:'proxy.init',args:{key:'p1-management'}}),e=>e.code==='read-only');assert.equal(calls.length,0);assert.deepEqual(await f.b.request(f.human,{verb:'proxy.init',args:{key:'p1-management',port:18432}}),{port:18432,binary:'/fixture'});assert.equal(JSON.stringify(f.store.all('SELECT body FROM events')).includes('p1-management'),false);}); for(const [code,args]of [['proxy-key-invalid',{key:'a\nb'}],['proxy-config-invalid',{key:'p1-management',port:8317}],['invalid-request',{key:'p1-management',binary:'/forged'}]])test(`proxy.init ${code}`,t=>{const f=fixture(t,()=>{throw Error('must not call');});assert.throws(()=>f.b.request(f.human,{verb:'proxy.init',args}),e=>e.code===code);}); test('proxy.init not-configured',t=>{const f=fixture(t,null);assert.throws(()=>f.b.request(f.human,{verb:'proxy.init',args:{key:'p1-management'}}),e=>e.code==='not-configured');}); test('proxy.init callback error redacts key and maps outcome to named refusal',async t=>{const f=fixture(t,()=>{throw Error('p1-management');});await assert.rejects(f.b.request(f.human,{verb:'proxy.init',args:{key:'p1-management'}}),e=>e.code==='proxy-init-failed'&&!e.message.includes('p1-management'));assert.equal(JSON.stringify(f.store.all('SELECT body FROM events')).includes('p1-management'),false);}); test('socket awaits proxy.init and does not return a Promise object or retain human cap',async t=>{const {serve}=await import('../src/server.mjs');const {Client}=await import('../src/client.mjs');const f=fixture(t,async()=>{await new Promise(r=>setTimeout(r,10));return {port:18432,binary:'/fixture'};});const root=mkdtempSync(join(tmpdir(),'p1-sock-'));const socket=join(root,'s');const server=await serve({broker:f.b,path:socket,peerReader:{read:async()=>({pid:process.pid,uid:process.getuid(),gid:process.getgid()}),close(){}},authenticateHuman:()=>f.b.bindHuman({business:'demo',human:'owner',via:'cli',outsideAgent:true})});t.after(()=>server.close());const client=new Client({path:socket,human:{business:'demo',pid:process.pid,startTime:'1',nonce:'fixture'}});assert.deepEqual(await client.call('proxy.init',{key:'p1-management'}),{port:18432,binary:'/fixture'});}); test('proxy-init-failed: extra callback fields cannot return a management key',async t=>{const f=fixture(t,async()=>({port:18432,binary:'/fixture',key:'p1-management'}));await assert.rejects(f.b.request(f.human,{verb:'proxy.init',args:{key:'p1-management'}}),e=>e.code==='proxy-init-failed');assert.equal(JSON.stringify(f.store.all('SELECT body FROM events')).includes('p1-management'),false);}); // P2 R2-N1: catches local broker predicates diverging from management-client rules. for (const [label, key] of [['Latin-1', 'fx331-caf\u00e9'], ['leading space', ' fx331-key'], ['trailing space', 'fx331-key '], ['internal space', 'fx331 key']]) { test(`proxy-key-invalid: broker rejects ${label} before initializer`, async t => { let called = false; const f = fixture(t, () => { called = true; return { port: 18432, binary: '/fixture' }; }); let pending; try { assert.throws(() => { pending = f.b.request(f.human, { verb: 'proxy.init', args: { key } }); }, e => e.code === 'proxy-key-invalid'); } finally { await Promise.resolve(pending).catch(() => {}); } assert.equal(called, false); assert.equal(JSON.stringify(f.store.all('SELECT body FROM events')).includes(key), false); }); } for (const [field, code, value] of [['rotateGraceMinutes', 'proxy-rotate-grace-invalid', 1441], ['firstOutputSeconds', 'proxy-first-output-invalid', 3601]]) { test(`proxy.init ${code}: human setting validated before initializer`, t => { let called = false; const f = fixture(t, () => { called = true; }); assert.throws(() => f.b.request(f.human, { verb: 'proxy.init', args: { key: 'fx331-manage', [field]: value } }), e => e.code === code); assert.equal(called, false); }); }