/** Pure YAML roster checks. Bundle with the host's yaml dependency and run from the repository root. */ import assert from 'node:assert/strict' import { readFileSync, readdirSync, existsSync } from 'node:fs' import { parseConfig, parseFrontmatter, definitionRuns, toolsFor } from './agents.ts' let count = 0 function test(name: string, run: () => void) { run(); console.log(`ok ${++count} - ${name}`) } const text=readFileSync('config/config.yaml','utf8') const config=parseConfig(text) const fixture=()=>({standing:'worker',prompt:'Shared context',roster:[{name:'worker',description:'Worker',model:'faux/faux-1',thinking:'low',prompt:'Role context',tools:['read']}]}) test('default config contains the full roster and the configured standing model',()=>{ assert.deepEqual(config.definitions.map(d=>d.name),['coordinator','designer','dream-pass','reviewer-architecture','reviewer-correctness','reviewer-simplicity','reviewer','scout','sausage','watcher','worker']) const standing=config.definitions.find(d=>d.name===config.standing)! assert.deepEqual(definitionRuns(standing),{model:{provider:'anthropic',modelId:'claude-opus-5-5'},thinking:'high'}) assert(standing.instructions.includes('systemctl restart chat')) assert(standing.instructions.includes('instead of guessing')) }) test('global prompt states each harness route, the proc files, and the config path',()=>{ for(const value of ['http://host.sausage/harness/','whoami','conversations','conversations/ID/entries?after=N','events?after=N','models','extensions','credential-requests','/proc/processes','/proc/extensions','jaq','/etc/sausage/config.yaml']) assert(config.prompt.includes(value),value) }) test('YAML block scalars keep the shared and role prompts separate',()=>{ assert(config.prompt.startsWith('## Sausage and the world')) assert(config.prompt.includes('\n\n## Inspect the harness state')) assert(!config.prompt.includes('# Standing agent')) assert(config.definitions.every(d=>d.instructions.includes('\n'))) }) test('JSON is valid YAML and model references preserve slashes in the model id',()=>{ const value=fixture();value.roster[0].model='faux/org/model' assert.deepEqual(definitionRuns(parseConfig(JSON.stringify(value)).definitions[0]).model,{provider:'faux',modelId:'org/model'}) }) test('reject missing global prompt, unknown standing name, and duplicate roster names',()=>{ const value=fixture() assert.throws(()=>parseConfig(JSON.stringify({...value,prompt:null})),/prompt must be a string/) assert.throws(()=>parseConfig(JSON.stringify({...value,standing:'missing'})),/standing must name a roster member/) assert.throws(()=>parseConfig(JSON.stringify({...value,roster:[...value.roster,...value.roster]})),/duplicate agent/) }) test('reject malformed YAML and invalid roster fields',()=>{ assert.throws(()=>parseConfig('roster: [\n')) for(const patch of [{name:'with space'},{description:''},{prompt:''},{model:'missing-provider'},{thinking:'no'},{tools:'read'},{denyTools:[1]}]) { const value=fixture();Object.assign(value.roster[0],patch) assert.throws(()=>parseConfig(JSON.stringify(value)),/config.yaml/) } }) test('tool denials also apply to inherited tools without changing the parent',()=>{ const definition=parseConfig(JSON.stringify(fixture())).definitions[0] const parent=['read','write'] delete definition.tools;definition.addTools=['bash'];definition.denyTools=['write'] assert.deepEqual(toolsFor(definition,parent),['read','bash']) assert.deepEqual(parent,['read','write']) }) test('skill frontmatter uses the same YAML parser',()=>{ const parsed=parseFrontmatter('---\r\nname: skill\r\ndescription: >\r\n First line\r\n second line\r\n---\r\nBody') assert.equal(parsed.frontmatter.name,'skill') assert.equal(parsed.frontmatter.description,'First line second line\n') assert.equal(parsed.body,'Body') }) test('every built-in skill has its matching name, description, and instructions',()=>{ for (const folder of readdirSync('skills')) { const path=`skills/${folder}/SKILL.md` if (!existsSync(path)) continue const {frontmatter,body}=parseFrontmatter(readFileSync(path,'utf8')) assert.equal(frontmatter.name,folder,path) assert.equal(typeof frontmatter.description,'string',path) assert(body.trim(),path) } }) console.log(`${count} tests passed`)