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, BusError } from '../src/broker.mjs'; function fixture(t, project, secretCheck = () => {}) { const root = mkdtempSync(join(tmpdir(), 'project-await-')); const store = new Store(root); t.after(() => { store.close(); rmSync(root, { recursive: true, force: true }); }); const business = { 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: { definition: 'coder', authority: { withinRole: ['record.write'], crossRole: [] } }, } }; const broker = new Broker({ store, businesses: { demo: business }, project, secretCheck }); const cap = broker.bindLaunch({ business: 'demo', role: 'coder', run: 'run', harness: 'pi', address: 'coder' }); const call = (verb, args = {}) => broker.request(cap, { verb, args }); call('role.claim'); return { broker, cap, call, store }; } test('D1: committed write with a failed receipt refuses outcome-unknown without action.allowed', async t => { let f, committed = false; f = fixture(t, { async writeRecord() { committed = true; f.call('role.release'); return { path: 'docs/result.md', commit: 'a'.repeat(40) }; } }); let returned; await assert.rejects(async () => { returned = await f.call('record.write', { project: 'stack', path: 'docs/result.md', record: '# Result' }); }, { code: 'outcome-unknown' }); assert.equal(committed, true); assert.equal(returned, undefined); assert.deepEqual(f.store.all("SELECT body FROM events WHERE kind='action.allowed' AND json_extract(body,'$.action')='record.write'"), []); }); test('D2: spec.read refuses without content if its role is released during the read', async t => { let f; f = fixture(t, { async readSpec() { f.call('role.release'); return { content: 'CONTENT-MUST-NOT-RETURN' }; } }); let returned; await assert.rejects(async () => { returned = await f.call('spec.read', { project: 'stack' }); }, { code: 'not-holder' }); assert.equal(returned, undefined); assert.ok(!JSON.stringify(f.store.all('SELECT body FROM events')).includes('CONTENT-MUST-NOT-RETURN')); }); for (const field of ['content', 'subject']) test(`D3: spec.read secret check refuses flagged ${field} without content`, async t => { const marker = 'FLAGGED-SPEC-VALUE'; const result = { content: field === 'content' ? marker : '# Safe', log: [{ subject: field === 'subject' ? marker : 'Safe' }] }; const f = fixture(t, { async readSpec() { return result; } }, value => { if (JSON.stringify(value).includes(marker)) throw new BusError('secret-refused'); }); let returned; await assert.rejects(async () => { returned = await f.call('spec.read', { project: 'stack' }); }, { code: 'secret-refused' }); assert.equal(returned, undefined); assert.ok(!JSON.stringify(f.store.all('SELECT body FROM events')).includes(marker)); });