import test from 'node:test'; import assert from 'node:assert/strict'; import { pathToFileURL } from 'node:url'; import { resolve } from 'node:path'; const root=process.env.MOSAIC_REVIEW_ROOT ?? new URL('./wt/',import.meta.url).pathname; const moduleAt=path=>import(pathToFileURL(resolve(root,path))); const { world }=await moduleAt('packages/tasks/tests/world.mjs'); const { loadRequirements, checkRequirements, RequirementsError }=await moduleAt('packages/tasks/src/requirements.mjs'); const { turnRequest }=await moduleAt('packages/harness/src/runner.mjs'); const raw=()=>structuredClone(loadRequirements()); test('every approved requirement creates, preserving its id', async t=>{ const w=await world(t); await w.adapter.start('demo'); const pm=w.agent('pm'); const {requirements}=loadRequirements(); for(const {id} of requirements) await w.call(pm,'task.create',{title:id,request:w.instruction(),requirement:id}); assert.deepEqual(w.events('task.created').map(e=>e.body.requirement),requirements.map(r=>r.id)); }); test('the received human request is visible in the runner header and creates a task',async t=>{ const w=await world(t); await w.adapter.start('demo'); const pm=w.agent('pm'); w.broker.request(w.human,{verb:'message.send',args:{to:'pm',body:'do this'}}); const [message]=w.broker.request(pm,{verb:'message.receive'}); const header=turnRequest(message); assert.ok(header.includes(`request ${message.request}`)); const request=header.match(/, request ([^:]+):\n/)[1]; assert.equal(request,message.request); await w.call(pm,'task.create',{title:'header request',request,requirement:'REQ-TASK-1'}); }); test('inherited top keys refuse',()=>{ const l=raw(); const inherited=Object.create({prd:l.prd}); inherited.version=l.version; inherited.requirements=l.requirements; assert.throws(()=>checkRequirements(inherited), e=>e instanceof RequirementsError && e.message==='list: missing prd'); }); test('inherited entry keys refuse',()=>{ const l=raw(); const r=l.requirements[0]; l.requirements[0]=Object.assign(Object.create({id:r.id}),{title:r.title}); assert.throws(()=>checkRequirements(l),e=>e instanceof RequirementsError && e.message==='requirements[0]: missing id'); }); test('null prototypes are accepted when all required keys are own',()=>{ const l=Object.assign(Object.create(null),raw()); l.requirements=l.requirements.map(r=>Object.assign(Object.create(null),r)); assert.equal(checkRequirements(l),l); }); test('carriage return is accepted in a title (documented minor boundary)',()=>{ const l=raw(); l.requirements[0].title='one\rtwo'; assert.equal(checkRequirements(l),l); });