46 lines
4.1 KiB
JavaScript
46 lines
4.1 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { mkdtempSync, rmSync } from 'node:fs';
|
|
import { tmpdir } from 'node:os';
|
|
import { join } from 'node:path';
|
|
import { Store } from '../src/store.mjs';
|
|
import { Broker } from '../src/broker.mjs';
|
|
import { createLimits, modelUsageKey } from '../src/limits.mjs';
|
|
const key='012345abcdef';
|
|
test('P5 broker preserves original plugin subject and derives internal run context from authenticated native caller',async t=>{
|
|
const root=mkdtempSync(join(tmpdir(),'p5-context-')),store=new Store(root),asked=[];t.after(()=>{store.close();rmSync(root,{recursive:true,force:true});});
|
|
const b=new Broker({store,businesses:{demo:{id:'demo',human:'jason',arbiters:{technical:'chief',delivery:'chief'},roles:{chief: { definition: 'chief-of-staff', authority: { withinRole: ['decision.resolve.technical', 'decision.resolve.delivery'], crossRole: [] } }, coder:{authority:{withinRole:[],crossRole:[]}}}}},
|
|
limits:{mustStop:async(...args)=>{asked.push(args);return {stop:false};}},usage:{collect:async()=>({recorded:true}),view:()=>({})}});
|
|
const human=b.bindHuman({business:'demo',human:'jason',via:'cli',outsideAgent:true});
|
|
const cap=b.bindLaunch({business:'demo',role:'coder',run:'native-run',harness:'pi',provider:'fixture',model:'fake'});b.request(cap,{verb:'role.claim'});
|
|
const {id}=b.request(human,{verb:'message.send',args:{to:'coder',body:'work'}});b.request(cap,{verb:'message.receive'});
|
|
await b.request(cap,{verb:'usage.begin',args:{turn:id}});
|
|
await assert.rejects(b.request(cap,{verb:'usage.end',args:{turn:id,run:'forged-run'}}),{code:'invalid-request'});
|
|
assert.equal(asked.length,0);
|
|
await b.request(cap,{verb:'usage.end',args:{turn:id}});
|
|
assert.deepEqual(asked,[['demo',{instance:'coder',provider:'fixture',model:'fake',account:null},{run:'native-run'}]]);
|
|
});
|
|
test('P5 configured key quotas never use a supplied safe-looking ID when trusted metadata lookup is missing',async t=>{
|
|
const root=mkdtempSync(join(tmpdir(),'p5-no-bypass-')),store=new Store(root);t.after(()=>{store.close();rmSync(root,{recursive:true,force:true});});
|
|
const doc={plugins:{'limit-check':['daily-quota']},launch:{limits:{tokens:{keys:{[key]:{limit:10,since:'2026-01-01T00:00:00.000Z',reset:'00:00',timeZone:'UTC'}}}}}};
|
|
const limits=createLimits({store,read:()=>doc,log:()=>{},keyForSubject:()=>null});
|
|
assert.deepEqual(await limits.mustStop('demo',{instance:'coder',modelKeyId:key},{run:'forged-run'}),{stop:true,check:null,code:'proxy-key-refused'});
|
|
});
|
|
test('P5 internal context resolves exactly current or retained generation; wrong business, instance, run and owner refuse',()=>{
|
|
// Row 333 R3 ruling 2: no owner record at all is key-quota-no-model-key; a wrong run stays proxy-key-refused.
|
|
const newer='abcdef012345',rows=[{instance:'demo/coder',service:'model',keyId:newer,retiring:[{keyId:key}]}];
|
|
const runs=new Map([['demo:old',{instance:'demo/coder',keyId:key}],['demo:new',{instance:'demo/coder',keyId:newer}],['other:wrong',{instance:'demo/coder',keyId:key}]]);
|
|
assert.equal(modelUsageKey(rows,runs,'demo',{instance:'coder'}),newer);
|
|
assert.equal(modelUsageKey(rows,runs,'demo',{instance:'coder',run:'old'}),key);
|
|
assert.equal(modelUsageKey(rows,runs,'demo',{instance:'coder',run:'new'}),newer);
|
|
for(const [business,subject,code] of [['other',{instance:'coder',run:'wrong'},'key-quota-no-model-key'],['demo',{instance:'other',run:'old'},'key-quota-no-model-key'],['demo',{instance:'coder',run:'wrong'},'proxy-key-refused']])
|
|
assert.throws(()=>modelUsageKey(rows,runs,business,subject),{code});
|
|
});
|
|
|
|
test('P5 model-key mustStop without native run context fails closed even when the current key resolves',async t=>{
|
|
const root=mkdtempSync(join(tmpdir(),'p5-missing-context-')),store=new Store(root);t.after(()=>{store.close();rmSync(root,{recursive:true,force:true});});
|
|
const doc={plugins:{'limit-check':['daily-quota']},launch:{limits:{tokens:{keys:{[key]:{limit:10,since:'2026-01-01T00:00:00.000Z',reset:'00:00',timeZone:'UTC'}}}}}};
|
|
const limits=createLimits({store,read:()=>doc,log:()=>{},keyForSubject:()=>key});
|
|
assert.deepEqual(await limits.mustStop('demo',{instance:'coder'}),{stop:true,check:null,code:'proxy-key-refused'});
|
|
});
|