// --- T-I8 one-shot (row 190): the default instance's renders and outputs from the base da230ca48 // scripts and templates and from the candidate, in one fixture. Not committed; BUILD.md records it. const BASE_SHA='da230ca48'; const repoBase=join(base,'repo-base'); cpSync(repo,repoBase,{recursive:true}); const changed=['packages/cli/systemd/mosaic-bus.service.in','packages/conversation/src/guard.mjs','packages/discord/systemd/mosaic-discord@.service.in','packages/webui/systemd/mosaic-webui.service.in','scripts/bootstrap.sh','scripts/bus-service.sh','scripts/discord-service.sh','scripts/mosaic-config.mjs','scripts/stack-copy.sh','scripts/stack-release.sh','scripts/webui-service.sh']; for(const f of changed)writeFileSync(join(repoBase,f),execFileSync('git',['-C',ROOT,'show',`${BASE_SHA}:${f}`])); rmSync(join(repoBase,'scripts','instance.sh')); for(const f of changed)assert.notEqual(sha(join(repoBase,f)),sha(join(repo,f)),f); const SR_BASE=join(repoBase,'scripts','stack-release.sh'); const both=async(e,...args)=>{const c=await run({...e,sr:SR},...args),b=await run({...e,sr:SR_BASE},...args);return [c,b]}; const sh2=(r,e,name,...a)=>spawnSync('bash',[join(r,'scripts',name),...a],{env:e.env,encoding:'utf8'}); const OUT=process.env.TI8_OUT; const record=(label,c,b)=>appendFileSync(OUT,`== ${label}\ncandidate code ${c.code??c.status} sha ${createHash('sha256').update(c.out??c.stdout).digest('hex')} err ${createHash('sha256').update(c.err??c.stderr).digest('hex')}\nbase code ${b.code??b.status} sha ${createHash('sha256').update(b.out??b.stdout).digest('hex')} err ${createHash('sha256').update(b.err??b.stderr).digest('hex')}\n`); // The one path that differs by design: each script names its own repository (--checkout, REPO). const norm=(r)=>({code:r.code??r.status,out:(r.out??r.stdout).replaceAll(repoBase,repo),err:(r.err??r.stderr).replaceAll(repoBase,repo)}); const same=(label,c0,b0)=>{const c=norm(c0),b=norm(b0);record(label,c,b);assert.equal(c.code??c.status,b.code??b.status,label);assert.equal(c.out??c.stdout,b.out??b.stdout,label);assert.equal(c.err??c.stderr,b.err??b.stderr,label)}; test('T-I8 one-shot: the default instance prints and renders the same from the base and the candidate',async(t)=>{ const e=await mk(t);await seed(e); for(const [name,args] of [ ['bus-service.sh',['render','--copy',B,'--copies',COPIES,'--claude',e.claude]], ['bus-service.sh',['render','--copy',B,'--copies',COPIES,'--pm','--claude',e.claude]], ['webui-service.sh',['render','--copy',B,'--copies',COPIES,'--port',e.port,'--business','acme']], ['webui-service.sh',['render','--copy',B,'--copies',COPIES,'--port',e.port,'--business','acme','--tester-port','7341']], ['discord-service.sh',['render']], ['stack-copy.sh',['check','--copies',COPIES,'--bin',e.bin]], ['stack-copy.sh',['check','--copies',COPIES,'--bin',e.bin,'--business','acme']], ]){ const c=sh2(repo,e,name,...args),b=sh2(repoBase,e,name,...args); assert.equal(c.status,0,`${name} ${args.join(' ')}: ${c.stderr}`); same(`${name} ${args.join(' ')}`,c,b); } for(const args of [['status','acme'],['activate',C1,'acme','--plan'],['activate',C1,'acme','--tester-port','7341','--plan'],['activate',C,'acme','--migrate','--plan'],['activate',B,'acme','--plan'],['rollback','acme','--plan']]){ const [c,b]=await both(e,...args);same(args.join(' '),c,b); } assert.equal((await run(e,'activate',C1,'acme')).code,0); for(const args of [['status','acme'],['rollback','acme','--plan']]){const [c,b]=await both(e,...args);same(`after activate C1: ${args.join(' ')}`,c,b)} });