Files
TORCH/test/fleet/organization.test.mjs

157 lines
8.9 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { projectConfigSchema } from '../../src/kernel/config.mjs';
import { planManagerCheckInSchedules, validateOrganizationGraph } from '../../src/kernel/organization.mjs';
function graph() {
return {
schema: 'torch.dev/organization/v1alpha1', revision: 1,
owner_facing_role: 'session-manager',
roles: [
{
id: 'owner', title: 'Project Owner', kind: 'owner', identity_id: 'owner',
responsibilities: ['Set product direction and approve organization changes.'],
authority: ['approve-organization', 'approve-release'],
coordinates: [], reports_to: [], consults_with: [],
},
{
id: 'session-manager', title: 'Session Manager', kind: 'owner-facing', identity_id: 'session-manager',
responsibilities: ['Receive owner requests and route project work.'],
authority: ['receive-owner-requests', 'propose-priorities'],
coordinates: ['runtime-lead', 'runtime-specialist'], reports_to: [], consults_with: [],
},
{
id: 'runtime-lead', title: 'Runtime Lead', kind: 'domain-coordination', identity_id: 'runtime-lead',
responsibilities: ['Coordinate runtime integration across specialists.'],
authority: ['coordinate-domains', 'sequence-domains'],
coordinates: ['runtime-specialist'], reports_to: ['session-manager'], consults_with: ['runtime-specialist'],
},
{
id: 'runtime-specialist', title: 'Runtime Specialist', kind: 'specialist', identity_id: 'runtime',
responsibilities: ['Implement the runtime subsystem.'],
authority: ['own-implementation'], coordinates: [], reports_to: ['runtime-lead'], consults_with: ['runtime-lead'],
},
],
implementation_owners: [{ surface: 'src/runtime/**', identity_id: 'runtime' }],
};
}
test('SCN-organization-graph: versioned hierarchy separates implementation, coordination, and owner authority', () => {
const candidate = graph();
assert.equal(validateOrganizationGraph(candidate), candidate);
assert.equal(projectConfigSchema.shape.organization.safeParse(candidate).success, true);
});
test('SCN-organization-graph: allows a specialist identity to be promoted while retaining its implementation role', () => {
const candidate = graph();
candidate.roles.push({
id: 'runtime-promoted-lead', title: 'Runtime Integration Lead', kind: 'domain-coordination', identity_id: 'runtime',
responsibilities: ['Coordinate runtime and simulation integration.'],
authority: ['coordinate-domains'], coordinates: ['runtime-specialist'],
reports_to: ['session-manager'], consults_with: ['runtime-specialist'],
});
assert.equal(validateOrganizationGraph(candidate), candidate);
});
test('SCN-organization-graph: rejects duplicate implementation owners and owner-only approval leakage', () => {
const candidate = graph();
candidate.implementation_owners.push({ surface: 'src/runtime/**', identity_id: 'runtime' });
candidate.roles[2].authority.push('approve-release');
assert.throws(() => validateOrganizationGraph(candidate), (error) => {
assert.equal(error.code, 'ORGANIZATION_GRAPH_INVALID');
assert.match(JSON.stringify(error.details), /multiple owners/);
assert.match(JSON.stringify(error.details), /owner-reserved approval authority/);
return true;
});
});
test('SCN-organization-graph: rejects reporting cycles and unknown role references', () => {
const candidate = graph();
candidate.roles[1].reports_to = ['runtime-lead'];
candidate.roles[2].reports_to = ['session-manager'];
candidate.roles[3].coordinates = ['missing-role'];
assert.throws(() => validateOrganizationGraph(candidate), (error) => {
assert.equal(error.code, 'ORGANIZATION_GRAPH_INVALID');
assert.match(JSON.stringify(error.details), /acyclic/);
assert.match(JSON.stringify(error.details), /unknown role reference/);
return true;
});
});
test('SCN-manager-schedule-coverage / SCN-manager-check-in-cadence-floor: managers require owner-gated cadence with a 60-second minimum', () => {
const domain = (id, title, path) => ({
id, title, scope: [`Own ${title}.`], not_scope: [], owned_paths: [path], shared_paths: [],
neighbours: [], required_checks: [], resources: [], runtime: 'claude',
});
const schedule = (managerId) => ({
id: `${managerId}-check-in`, title: `${managerId} direct-report check-in`, owner: managerId,
lifetime: 'system', trigger: { type: 'interval', seconds: 900 }, behavior: 'coordination',
action: { type: 'manager-check-in', manager_id: managerId }, required_authority: ['owner'],
retry: { max_attempts: 1 }, failure_recipient: managerId,
source_of_truth: 'active organization direct-report graph',
});
const config = {
schema: 'torch.dev/v1alpha1', project: { id: 'test-project', name: 'Test', main_branch: 'main' },
paths: { tracked_state: '.torch', worktree_parent: '/tmp/worktrees' },
repository: { canonical: { type: 'unconfigured' } }, forge: { provider: 'none' },
git: { branch_prefix: 'torch/', convergence: 'merge', allow_rebase: false, allow_force_push: false, allow_bare_stash: false },
synchronization: { strategy: 'dispatcher-managed', auto_merge_worktrees: false },
runtimes: { default: 'claude', claude: {} }, checks: [], resources: [],
schedules: [schedule('session-manager')],
integration: { provider: 'torch', target: 'main', require_current_main: true, required_checks: [], landing_authority: ['session-manager'] },
delivery: {
authority: Object.fromEntries(['implemented', 'verified', 'integrated', 'release_ready', 'released', 'deployed', 'live_verified']
.map((key) => [key, ['owner']])),
adapters: { release: { provider: 'none' }, deployment: { provider: 'none' } },
},
session_manager: { id: 'session-manager', runtime: 'claude', start_last: true },
domains: [domain('runtime-lead', 'Runtime Lead', 'src/runtime-lead/**'), domain('runtime', 'Runtime', 'src/runtime/**')],
organization: graph(),
};
const missing = projectConfigSchema.safeParse(config);
assert.equal(missing.success, false);
assert.match(JSON.stringify(missing.error.issues), /runtime-lead.*manager-check-in schedule/);
config.schedules.push(schedule('runtime-lead'));
assert.equal(projectConfigSchema.safeParse(config).success, true);
config.schedules[0].action.wake = { enabled: true };
const missingWakeBudget = projectConfigSchema.safeParse(config);
assert.equal(missingWakeBudget.success, false);
assert.match(JSON.stringify(missingWakeBudget.error.issues), /project-wide daily invocation budget/);
assert.match(JSON.stringify(missingWakeBudget.error.issues), /positive per-invocation USD ceiling/);
config.runtime_wake_budget = { max_invocations_per_day: 2 };
const missingDollarCeiling = projectConfigSchema.safeParse(config);
assert.equal(missingDollarCeiling.success, false);
config.schedules[0].action.wake.max_usd_per_invocation = 0.25;
assert.equal(projectConfigSchema.safeParse(config).success, true);
config.schedules[0].trigger.seconds = 59;
const tooFrequent = projectConfigSchema.safeParse(config);
assert.equal(tooFrequent.success, false);
assert.match(JSON.stringify(tooFrequent.error.issues), /manager check-in intervals must be at least 60 seconds/);
config.schedules[0].trigger.seconds = 60;
assert.equal(projectConfigSchema.safeParse(config).success, true, 'one-minute manager polling remains valid');
});
test('SCN-manager-schedule-growth: hierarchy planning adds schedules for new managers and preserves configured cadence', () => {
const existing = {
id: 'session-manager-check-in', title: 'Custom Session Manager cadence', owner: 'session-manager',
lifetime: 'system', trigger: { type: 'interval', seconds: 600 }, behavior: 'coordination',
action: { type: 'manager-check-in', manager_id: 'session-manager' }, required_authority: ['owner'],
retry: { max_attempts: 1 }, failure_recipient: 'session-manager',
source_of_truth: 'active organization direct-report graph',
};
const plan = planManagerCheckInSchedules({ graph: graph(), schedules: [existing] });
assert.deepEqual(plan.coveredManagerIds, ['runtime-lead', 'session-manager']);
assert.equal(plan.schedules[0], existing, 'existing cadence and settings stay intact');
assert.deepEqual(plan.additions.map((schedule) => [schedule.action.manager_id, schedule.trigger.seconds]), [
['runtime-lead', 900],
]);
assert.equal(plan.additions[0].required_authority.includes('owner'), true);
assert.equal(plan.mutationPerformed, false);
const noLongerManager = structuredClone(graph());
noLongerManager.roles.find((role) => role.id === 'runtime-specialist').reports_to = [];
const changed = planManagerCheckInSchedules({ graph: noLongerManager, schedules: [existing, ...plan.additions] });
assert.deepEqual(changed.obsolete.map((schedule) => schedule.action.manager_id), ['runtime-lead']);
assert.equal(changed.schedules.length, 2, 'obsolete timers are surfaced but not silently removed');
});