mirror of
https://github.com/PR0M3TH3AN/TORCH.git
synced 2026-10-29 08:51:53 +00:00
190 lines
12 KiB
JavaScript
190 lines
12 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import { execFileSync } from 'node:child_process';
|
|
import { mkdtempSync, readFileSync, writeFileSync } from 'node:fs';
|
|
import { tmpdir } from 'node:os';
|
|
import { basename, join } from 'node:path';
|
|
import test from 'node:test';
|
|
import { openControlPlane } from '../../src/control-plane/service.mjs';
|
|
import { analyzeRepository } from '../../src/kernel/analyze.mjs';
|
|
import { proposeDomains } from '../../src/kernel/domains.mjs';
|
|
import { inspectRepository } from '../../src/kernel/git.mjs';
|
|
import { installProject } from '../../src/kernel/install.mjs';
|
|
import { callTorchTool } from '../../src/mcp/tools.mjs';
|
|
import { planManagerCheckIn, queueManagerCheckIn } from '../../src/observability/manager-checkin.mjs';
|
|
import { BacklogService } from '../../src/backlog/service.mjs';
|
|
import { createWorktrees } from '../../src/kernel/worktrees.mjs';
|
|
|
|
function fixture() {
|
|
const root = mkdtempSync(join(tmpdir(), 'torch-manager-check-in-'));
|
|
execFileSync('git', ['init', '-b', 'main', root]);
|
|
execFileSync('git', ['-C', root, 'config', 'user.email', '[email protected]']);
|
|
execFileSync('git', ['-C', root, 'config', 'user.name', 'TORCH Test']);
|
|
writeFileSync(join(root, 'app.js'), 'export const app = true;\n');
|
|
execFileSync('git', ['-C', root, 'add', '.']);
|
|
execFileSync('git', ['-C', root, 'commit', '-m', 'fixture']);
|
|
const repository = inspectRepository(root);
|
|
const proposal = proposeDomains({ repository, analysis: analyzeRepository(repository) });
|
|
proposal.domains.push({
|
|
id: 'peer-ai', title: 'Peer AI', scope: ['Review cross-domain contracts.'], not_scope: [],
|
|
owned_paths: ['peer/**'], shared_paths: [], neighbours: [], required_checks: [],
|
|
resources: [], runtime: 'claude', evidence: [],
|
|
});
|
|
proposal.review = {
|
|
status: 'approved', reviewedAt: '2026-09-28T00:00:00Z', reviewedBy: 'fixture-owner', notes: [],
|
|
};
|
|
const env = { ...process.env, XDG_DATA_HOME: join(tmpdir(), `${basename(root)}-state`) };
|
|
installProject({ repository, proposal, env, projectId: 'manager-check-in-fixture' });
|
|
return { root, env, worker: proposal.domains[0].id };
|
|
}
|
|
|
|
test('SCN-manager-check-in and SCN-manager-check-in-refresh: manager scope follows direct reports, refreshes staleable wakes, and queues one durable non-approving check-in', () => {
|
|
const context = fixture();
|
|
const control = openControlPlane({ repositoryRoot: context.root, env: context.env });
|
|
control.reportStatus({ areaId: context.worker, state: 'waiting', summary: 'Need a decision.', task: 'TASK-42' });
|
|
const managerApproval = control.requestApproval({
|
|
requester: context.worker, approver: 'session-manager', task: 'TASK-42',
|
|
title: 'Accept shared interface', summary: 'Review the proposed event contract.', evidence: 'docs/contracts/event.md',
|
|
});
|
|
const ownerApproval = control.requestApproval({
|
|
requester: context.worker, approver: 'owner', task: 'TASK-42',
|
|
title: 'Approve scope change', summary: 'This changes the agreed project scope.',
|
|
});
|
|
const peerApprover = control.listAgents().find((agent) =>
|
|
agent.areaId !== context.worker && agent.areaId !== 'session-manager')?.areaId;
|
|
assert.ok(peerApprover, 'fixture must include another AI identity');
|
|
const peerApproval = control.requestApproval({
|
|
requester: context.worker, approver: peerApprover, task: 'TASK-42',
|
|
title: 'Review cross-domain contract', summary: 'A peer AI owns this interface decision.',
|
|
});
|
|
control.sendMessage({
|
|
sender: context.worker, recipient: 'session-manager', kind: 'blocker',
|
|
body: 'Task is blocked pending review.', references: { task: 'TASK-42' },
|
|
});
|
|
|
|
const plan = planManagerCheckIn({
|
|
repositoryRoot: context.root, controlPlane: control, managerId: 'session-manager',
|
|
at: new Date('2026-09-28T20:00:00Z'),
|
|
});
|
|
assert.equal(plan.directReports.some((report) => report.areaId === context.worker), true);
|
|
assert.equal(plan.attentionRequired, true);
|
|
assert.equal(plan.findings.some((finding) => finding.type === 'waiting-unclassified'), false);
|
|
assert.equal(plan.findings.some((finding) => finding.type === 'approval-wait'), true);
|
|
assert.equal(plan.findings.some((finding) => finding.type === 'unacknowledged-blocker'), true);
|
|
assert.deepEqual(plan.approvalWaits.map((wait) => [wait.id, wait.approverKind]).sort((a, b) => a[0].localeCompare(b[0])), [
|
|
[managerApproval.id, 'manager'], [ownerApproval.id, 'owner'], [peerApproval.id, 'peer-ai'],
|
|
].sort((a, b) => a[0].localeCompare(b[0])));
|
|
assert.equal(plan.approvalWaitDetection, 'structured');
|
|
assert.equal(plan.mutationPerformed, false);
|
|
|
|
const queued = queueManagerCheckIn({ repositoryRoot: context.root, controlPlane: control, managerId: 'session-manager' });
|
|
assert.equal(queued.queued, true);
|
|
const pending = control.readMessages({ recipient: 'session-manager', unacknowledgedOnly: true })
|
|
.find((message) => message.id === queued.messageId);
|
|
assert.equal(pending.kind, 'manager-check-in');
|
|
assert.match(pending.body, /Structured approval waits/);
|
|
assert.match(pending.body, /do not decide on their behalf/);
|
|
assert.match(pending.body, /snapshot captured at/i);
|
|
assert.match(pending.body, /torch_plan_manager_check_in/);
|
|
|
|
const lateApproval = control.requestApproval({
|
|
requester: context.worker, approver: 'owner', task: 'TASK-42',
|
|
title: 'Approve newly raised budget', summary: 'This approval appeared after the queued snapshot.',
|
|
});
|
|
const refreshed = callTorchTool(control, 'torch_plan_manager_check_in', {}, {
|
|
actorId: 'session-manager', repositoryRoot: context.root,
|
|
});
|
|
assert.equal(refreshed.managerId, 'session-manager');
|
|
assert.equal(refreshed.approvalWaits.some((wait) => wait.id === lateApproval.id), true,
|
|
'the manager refresh sees approvals created after its durable wake message');
|
|
assert.equal(refreshed.approvalWaits.find((wait) => wait.id === lateApproval.id).approverKind, 'owner');
|
|
assert.throws(() => callTorchTool(control, 'torch_plan_manager_check_in', {}, {
|
|
actorId: context.worker, repositoryRoot: context.root,
|
|
}), (error) => error.code === 'MANAGER_ROLE_NOT_FOUND');
|
|
|
|
const duplicate = queueManagerCheckIn({ repositoryRoot: context.root, controlPlane: control, managerId: 'session-manager' });
|
|
assert.equal(duplicate.queued, false);
|
|
assert.equal(duplicate.reason, 'check-in-already-pending');
|
|
assert.equal(control.readMessages({ recipient: 'session-manager' })
|
|
.filter((message) => message.kind === 'manager-check-in').length, 1);
|
|
assert.throws(() => control.decideApproval({
|
|
approvalId: ownerApproval.id, decidedBy: 'session-manager', decision: 'approved',
|
|
}), (error) => error.code === 'APPROVER_AUTHORITY_REQUIRED');
|
|
const decided = control.decideApproval({
|
|
approvalId: ownerApproval.id, decidedBy: 'owner', decision: 'rejected', note: 'Scope needs owner review.',
|
|
expectedRevision: ownerApproval.revision,
|
|
});
|
|
assert.equal(decided.status, 'rejected');
|
|
assert.equal(control.readMessages({ recipient: context.worker }).some((message) =>
|
|
message.kind === 'approval-decision' && message.body.includes('Scope needs owner review.')), true);
|
|
assert.equal(control.listApprovals({ actorId: 'owner' }).some((approval) => approval.id === ownerApproval.id), true);
|
|
control.close();
|
|
});
|
|
|
|
test('SCN-manager-check-in-specialist: a role with no direct reports produces no spurious attention', () => {
|
|
const context = fixture();
|
|
const control = openControlPlane({ repositoryRoot: context.root, env: context.env });
|
|
const result = planManagerCheckIn({
|
|
repositoryRoot: context.root, controlPlane: control, managerId: context.worker,
|
|
});
|
|
assert.deepEqual(result.directReports, []);
|
|
assert.equal(result.attentionRequired, false);
|
|
control.close();
|
|
});
|
|
|
|
test('SCN-manager-stale-work-review: owner requests lead a bounded read-only review, incomplete coverage never invents inactivity', () => {
|
|
const context = fixture();
|
|
execFileSync('git', ['-C', context.root, 'add', '.torch']);
|
|
execFileSync('git', ['-C', context.root, 'commit', '-m', 'approved installed fleet']);
|
|
createWorktrees({ repository: inspectRepository(context.root), parentOverride: join(tmpdir(), `${basename(context.root)}-worktrees`) });
|
|
const control = openControlPlane({ repositoryRoot: context.root, env: context.env });
|
|
try {
|
|
const backlog = new BacklogService({ repositoryRoot: context.root, controlPlane: control,
|
|
clock: () => new Date('2026-09-20T00:00:00Z') });
|
|
const fields = { title: 'Neglected owner request', description: 'Review instead of silently abandoning it.',
|
|
acceptanceCriteria: ['Review evidence'], affectedDomains: [context.worker] };
|
|
const ownerTask = backlog.createOwner({ ...fields, actorId: 'owner' });
|
|
const routine = backlog.create({ ...fields, title: 'Routine request', actorId: 'session-manager' });
|
|
let blocked = backlog.transition({ taskId: routine.id, actorId: 'session-manager',
|
|
to: 'ready', expectedRevision: routine.revision });
|
|
blocked = backlog.transition({ taskId: routine.id, actorId: 'session-manager', to: 'assigned',
|
|
owner: context.worker, expectedRevision: blocked.revision });
|
|
backlog.transition({ taskId: routine.id, actorId: context.worker, to: 'blocked',
|
|
blockedReason: 'Waiting on an external dependency', expectedRevision: blocked.revision });
|
|
const before = readFileSync(join(backlog.root, `${ownerTask.id}.json`), 'utf8');
|
|
const at = new Date('2026-10-05T00:00:00Z');
|
|
const options = { repositoryRoot: context.root, controlPlane: control, managerId: 'session-manager', at };
|
|
assert.equal(planManagerCheckIn(options).staleWorkReview, null, 'review is opt-in');
|
|
const plan = planManagerCheckIn({ ...options, staleWork: { max_items: 1 } });
|
|
assert.equal(plan.staleWorkReview.available, true);
|
|
assert.equal(plan.staleWorkReview.complete, true);
|
|
assert.equal(plan.staleWorkReview.staleCount, 2);
|
|
assert.equal(plan.staleWorkReview.stale[0].taskId, ownerTask.id);
|
|
assert.equal(plan.staleWorkReview.truncated, true);
|
|
assert.equal(plan.findings.filter((finding) => finding.type === 'stale-work').length, 1);
|
|
assert.equal(plan.findings.find((finding) => finding.type === 'stale-work').ownerRequested, true);
|
|
const queued = queueManagerCheckIn({ ...options, staleWork: {} });
|
|
assert.equal(queued.queued, true);
|
|
const message = control.readMessages({ recipient: 'session-manager' }).find((item) => item.id === queued.messageId);
|
|
assert.equal(message.kind, 'manager-stale-work-review');
|
|
assert.match(message.body, /stale_work_review/);
|
|
assert.match(message.body, /do not authorize closing/i);
|
|
assert.equal(queueManagerCheckIn({ ...options, staleWork: {} }).reason, 'check-in-already-pending');
|
|
assert.equal(readFileSync(join(backlog.root, `${ownerTask.id}.json`), 'utf8'), before);
|
|
assert.equal(backlog.get(routine.id).state, 'blocked');
|
|
const full = planManagerCheckIn({ ...options, staleWork: {} });
|
|
assert.equal(full.staleWorkReview.stale.find((task) => task.taskId === routine.id).expectedWaiting, true);
|
|
const unknown = planManagerCheckIn({ ...options, staleWork: { max_commits: 1 } });
|
|
assert.equal(unknown.staleWorkReview.complete, false);
|
|
assert.equal(unknown.staleWorkReview.staleCount, 0);
|
|
assert.equal(unknown.staleWorkReview.unknownCount, 2);
|
|
assert.equal(unknown.findings.some((finding) => finding.type === 'stale-work-coverage-unknown'), true);
|
|
const scoped = planManagerCheckIn({ ...options, managerId: context.worker, staleWork: {} });
|
|
assert.deepEqual(scoped.staleWorkReview.stale, [], 'specialists do not receive unassigned owner requests');
|
|
assert.throws(() => planManagerCheckIn({ ...options, staleWork: { stale_days: 0 } }),
|
|
(error) => error.code === 'MANAGER_STALE_WORK_INPUT_INVALID');
|
|
const mcp = callTorchTool(control, 'torch_plan_manager_check_in', { stale_work_review: true, max_items: 1 },
|
|
{ actorId: 'session-manager', repositoryRoot: context.root });
|
|
assert.equal(mcp.staleWorkReview.maxItems, 1);
|
|
} finally { control.close(); }
|
|
});
|