feat(fleet): add reviewed v1-to-v2 migration preview
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Jarvis
2026-07-15 22:04:51 -05:00
parent c1aecfabe9
commit 0e814324ca
21 changed files with 3282 additions and 45 deletions

View File

@@ -176,6 +176,7 @@ export async function executeFleetReconcile(
assertLocalRosterOnly(request.roster);
const validateRoster = request.deps.validateRoster ?? defaultValidateRoster(request);
await validateRoster(request.roster);
assertLifecycleSocketAuthority(request);
const plan = scopePlan(await observeFleet(request.roster, request.deps), request.agentName);
if (request.command === 'status' || request.command === 'doctor') {
@@ -477,6 +478,23 @@ function assertVerificationSafe(plan: FleetReconcilePlan): void {
}
}
function assertLifecycleSocketAuthority(request: FleetReconcileRequest): void {
const mayStart =
request.command === 'start' ||
request.command === 'restart' ||
((request.command === 'apply' || request.command === 'reconcile') &&
request.roster.agents.some(
(agent: FleetRosterV2Agent): boolean =>
agent.lifecycle.enabled && agent.lifecycle.desiredState === 'running',
));
if (mayStart && request.roster.tmux.socketName === '') {
throw new FleetReconcileError(
'lifecycle-precondition-failed',
'Default-server lifecycle start is unsupported by the fixed named-socket systemd units.',
);
}
}
function targetAgentsFor(roster: FleetRosterV2, agentName?: string): readonly FleetRosterV2Agent[] {
if (agentName === undefined) return roster.agents;
const agent = roster.agents.find(