Files
jason.woltjeandClaude Opus 5.5 3190ad762b bus, project: file-backed north-star specs with spec.read and record.write (row 138, #1632)
Row 138 round 2, Rocko's candidate e3f9a400 (43 paths) on 26a0b0fab.
Dewey approved (comment 28754) after round 1 changes (comment 28752):
D1-D5 mutants killed, the 17 touched test files run singly passed
124/124. Rocko's own run: 753 tests and 59/59 mutants killed.

The bus gains the project adapter through runtime.mjs, the way it
already injects the organization, so broker.mjs takes no new imports
and refuses with project-not-configured when no adapter is set. The
project socket timeout is 120s. Roles gain record.write. The schema
moves from 3e to 3f; the live migration follows MIGRATION.md and
needs Mos's window.

Sage's landing gate ran on c842686d5 plus the candidate: 25 steps,
all rc 0 (15 packages, 10 script suites), network sage-r138_default
removed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 20:49:44 -05:00

62 lines
4.6 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { mkdtempSync, rmSync, writeFileSync, readFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { execFileSync } from 'node:child_process';
import { fixture, git } from './spec-fixtures.mjs';
test('current citation is recorded; docs commits do not stale it and a new spec never reopens settlement', async t => {
const f = await fixture(t);
const d = await f.raise({ project: 'stack', spec_path: 'spec/north-star.md', spec_commit: f.commit });
const stored = f.store.get('SELECT spec_path,spec_commit FROM decisions WHERE id=?', d.id);
assert.equal(stored.spec_path, 'spec/north-star.md'); assert.equal(stored.spec_commit, f.commit);
f.call(f.human, 'decision.resolve', { id: d.id, choice: 'yes' });
await f.call(f.coder, 'record.write', { project: 'stack', path: 'docs/design.md', record: '# Design\n' });
await f.raise({ project: 'stack', spec_path: 'spec/north-star.md', spec_commit: f.commit });
f.save('# Updated\n');
assert.equal(f.store.get('SELECT op FROM decision_events WHERE decision=? ORDER BY seq DESC', d.id).op, 'resolved');
assert.equal(f.store.get('SELECT spec_commit FROM decisions WHERE id=?', d.id).spec_commit, f.commit);
assert.throws(() => f.call(f.human, 'decision.resolve', { id: d.id, choice: 'no' }), /decision-closed/);
});
test('stale, unconfirmed, missing and partial spec citations refuse without inserting a decision', async t => {
const f = await fixture(t), citation = { project: 'stack', spec_path: 'spec/north-star.md', spec_commit: f.commit };
const current = f.save('# Current\n');
await assert.rejects(f.raise(citation), { code: 'stale-spec' });
f.save('# Agent\n', 'coder.coder');
await assert.rejects(f.raise({ ...citation, spec_commit: git(f.repo, 'rev-parse', 'HEAD') }), { code: 'spec-unconfirmed' });
for (const args of [{ project: 'stack', spec_path: citation.spec_path }, { project: 'stack', spec_commit: current },
{ spec_path: citation.spec_path, spec_commit: current }, { ...citation, spec_path: 'docs/design.md' }])
await assert.rejects(f.raise(args), { code: 'invalid-spec-citation' });
git(f.repo, 'rm', '--', 'spec/north-star.md');
git(f.repo, '-c', 'user.name=jason', '-c', '[email protected]', 'commit', '-m', 'Missing');
await assert.rejects(f.raise(citation), { code: 'project-read-missing' });
assert.equal(f.store.get('SELECT count(*) n FROM decisions').n, 0);
});
test('uncited raises retain their synchronous path and spec read is available to any held role in its business', async t => {
const f = await fixture(t);
const d = f.raise({});
assert.equal(typeof d.then, 'undefined');
assert.equal(f.store.get('SELECT spec_commit FROM decisions WHERE id=?', d.id).spec_commit, null);
const spec = await f.call(f.reviewer, 'spec.read', { project: 'stack', commit: f.commit });
assert.equal(spec.commit, f.commit); assert.equal(spec.confirmed, true);
assert.equal(spec.content, readFileSync(join(f.repo, 'spec/north-star.md'), 'utf8'));
await assert.rejects(f.call(f.reviewer, 'spec.read', { project: 'other' }), { code: 'project-not-declared' });
await assert.rejects(f.call(f.reviewer, 'spec.read', { project: 'stack', business: 'other' }), { code: 'invalid-request' });
await assert.rejects(f.call(f.human, 'spec.read', { project: 'stack' }), { code: 'agent-required' });
});
test('record writes bind the session author, require authority and refuse spec and impersonation paths', async t => {
const f = await fixture(t);
const written = await f.call(f.coder, 'record.write', { project: 'stack', path: 'docs/result.md', record: '# Result\n' });
assert.equal(git(f.repo, 'show', '-s', '--format=%an', written.commit), 'coder.coder');
assert.equal(git(f.repo, 'show', '--format=', '--name-only', written.commit), 'docs/result.md');
await assert.rejects(f.call(f.coder, 'record.write', { project: 'stack', path: 'spec/north-star.md', record: '# Bad' }), { code: 'project-spec-human-only' });
await assert.rejects(f.call(f.coder, 'record.write', { project: 'stack', path: 'docs/x.md', record: '# Bad', author: { definition: 'human', instance: 'jason' } }), { code: 'invalid-request' });
await assert.rejects(f.call(f.reviewer, 'record.write', { project: 'stack', path: 'docs/x.md', record: '# Bad' }), { code: 'decision-required' });
const event = f.store.all("SELECT body FROM events WHERE kind='action.allowed'").map(r => JSON.parse(r.body)).find(r => r.action === 'record.write');
assert.equal(event.commit, written.commit); assert.equal(event.path, 'docs/result.md');
});