@ours.network/fleet 1.1.0-nightly.5 → 1.1.0-nightly.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,11 +4,12 @@ import type { OwnerChannelHandle, OwnerChannelManagementRequest } from '../owner
4
4
  import type { ScheduledLoopManagerHandle } from '../loops/manager.js';
5
5
  import type { SpawnOpts } from '../spawn.js';
6
6
  import type { ManagedFleetSpawnResult } from '../fleet-proxy.js';
7
+ import { type FleetAuditPresentation, type FleetCommandOutcomeClass } from '../fleet-command-audit.js';
7
8
  export interface ControlRequest {
8
9
  version: 1 | 2 | 3;
9
10
  id: string;
10
11
  token: string;
11
- command: 'status' | 'snapshot' | 'submit_prompt' | 'respond_permission' | 'interrupt' | 'follow' | 'events_since' | 'owner_channel_manage' | 'loop_status' | 'loop_run_now' | 'loop_disable' | 'loop_enable' | 'reload_config' | 'conversation_page' | 'conversation_follow' | 'submit_prompt_v2' | 'interrupt_v2' | 'respond_permission_v2' | 'fleet_spawn';
12
+ command: 'status' | 'snapshot' | 'submit_prompt' | 'respond_permission' | 'interrupt' | 'follow' | 'events_since' | 'owner_channel_manage' | 'loop_status' | 'loop_run_now' | 'loop_disable' | 'loop_enable' | 'reload_config' | 'conversation_page' | 'conversation_follow' | 'submit_prompt_v2' | 'interrupt_v2' | 'respond_permission_v2' | 'fleet_spawn' | 'fleet_audit_begin' | 'fleet_audit_finish';
12
13
  text?: string;
13
14
  permissionId?: string;
14
15
  optionId?: string;
@@ -30,6 +31,16 @@ export interface ControlRequest {
30
31
  sessionGeneration?: string;
31
32
  /** Typed managed-spawn request accepted only over the authenticated role control plane. */
32
33
  spawn?: SpawnOpts;
34
+ audit?: {
35
+ requestId?: string;
36
+ argv?: string[];
37
+ correlationId?: string;
38
+ class?: FleetCommandOutcomeClass;
39
+ exitCode?: number;
40
+ effect?: 'not_started' | 'completed' | 'unknown';
41
+ resourceIds?: Record<string, string>;
42
+ presentation?: FleetAuditPresentation;
43
+ };
33
44
  }
34
45
  export interface ControlResponse {
35
46
  version: 1;
@@ -105,6 +116,7 @@ export declare class RoleControlServer {
105
116
  private loopManager?;
106
117
  private reloadConfig?;
107
118
  private fleetSpawner?;
119
+ private fleetAuditor?;
108
120
  constructor(stateDir: string, session: AgentSession, log: (line: string) => void);
109
121
  start(): Promise<void>;
110
122
  close(): Promise<void>;
@@ -113,6 +125,7 @@ export declare class RoleControlServer {
113
125
  setLoopManager(loopManager: ScheduledLoopManagerHandle | undefined): void;
114
126
  setConfigReloader(reloadConfig: (() => Promise<unknown>) | undefined): void;
115
127
  setFleetSpawner(fleetSpawner: ((options: SpawnOpts) => Promise<ManagedFleetSpawnResult>) | undefined): void;
128
+ setFleetAuditor(auditor: RoleControlServer['fleetAuditor']): void;
116
129
  private accept;
117
130
  private handle;
118
131
  /** Version and capability gate shared by every conversation v3 command. */
@@ -3,6 +3,7 @@ import { chmodSync, existsSync, readFileSync, rmSync, writeFileSync } from 'node
3
3
  import { createConnection, createServer } from 'node:net';
4
4
  import { join } from 'node:path';
5
5
  import { SessionControlError } from './types.js';
6
+ import { validateFleetAuditBegin, validateFleetAuditFinish, } from '../fleet-command-audit.js';
6
7
  import { interruptSession, queueSessionPrompt, respondSessionPermission, respondSessionPermissionV2, } from '../application/session-mutations.js';
7
8
  const MAX_LINE_BYTES = 64 * 1024;
8
9
  /** Commands that require protocol version 3. */
@@ -119,6 +120,7 @@ export class RoleControlServer {
119
120
  loopManager;
120
121
  reloadConfig;
121
122
  fleetSpawner;
123
+ fleetAuditor;
122
124
  constructor(stateDir, session, log) {
123
125
  this.session = session;
124
126
  this.log = log;
@@ -164,6 +166,7 @@ export class RoleControlServer {
164
166
  setFleetSpawner(fleetSpawner) {
165
167
  this.fleetSpawner = fleetSpawner;
166
168
  }
169
+ setFleetAuditor(auditor) { this.fleetAuditor = auditor; }
167
170
  accept(socket) {
168
171
  this.sockets.add(socket);
169
172
  socket.setEncoding('utf8');
@@ -311,6 +314,38 @@ export class RoleControlServer {
311
314
  this.write(socket, { version: 1, id: request.id, ok: true, result });
312
315
  return;
313
316
  }
317
+ case 'fleet_audit_begin': {
318
+ if (!this.fleetAuditor)
319
+ throw new SessionControlError('rejected', 'fleet auditing is unavailable');
320
+ try {
321
+ validateFleetAuditBegin(request.audit);
322
+ }
323
+ catch {
324
+ throw new SessionControlError('rejected', 'valid fleet audit begin fields are required');
325
+ }
326
+ const result = await this.fleetAuditor.begin(request.audit.requestId, request.audit.argv);
327
+ this.write(socket, { version: 1, id: request.id, ok: true, result });
328
+ return;
329
+ }
330
+ case 'fleet_audit_finish': {
331
+ if (!this.fleetAuditor)
332
+ throw new SessionControlError('rejected', 'fleet auditing is unavailable');
333
+ try {
334
+ validateFleetAuditFinish(request.audit);
335
+ }
336
+ catch {
337
+ throw new SessionControlError('rejected', 'valid fleet audit finish fields are required');
338
+ }
339
+ const audit = request.audit;
340
+ const result = await this.fleetAuditor.finish({
341
+ correlationId: audit.correlationId, class: audit.class, effect: audit.effect,
342
+ ...(audit.exitCode === undefined ? {} : { exitCode: audit.exitCode }),
343
+ ...(audit.resourceIds ? { resourceIds: audit.resourceIds } : {}),
344
+ ...(audit.presentation ? { presentation: audit.presentation } : {}),
345
+ });
346
+ this.write(socket, { version: 1, id: request.id, ok: true, result });
347
+ return;
348
+ }
314
349
  case 'owner_channel_manage': {
315
350
  if (!request.ownerChannel || typeof request.ownerChannel.action !== 'string')
316
351
  throw new SessionControlError('rejected', 'owner-channel management action is required');
@@ -5,7 +5,7 @@ export declare const TEMP_STOP_REQUEST_FILE = ".temp-stop-request.json";
5
5
  export declare const TEMP_RECLAIM_BATCH = 32;
6
6
  export declare const TEMP_LAUNCH_GRACE_MS = 60000;
7
7
  export type TempSupervisorKind = 'systemd-transient' | 'launchd-transient' | 'detached';
8
- export type TempTerminationReason = 'identity-closed' | 'session-ended' | 'operator-stop' | 'supervisor-signal' | 'startup-failure' | 'stale-supervisor';
8
+ export type TempTerminationReason = 'identity-closed' | 'session-ended' | 'operator-stop' | 'supervisor-signal' | 'supervisor-recycle' | 'startup-failure' | 'stale-supervisor';
9
9
  export interface TempSupervisorRecord {
10
10
  version: 1;
11
11
  role: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ours.network/fleet",
3
- "version": "1.1.0-nightly.5",
3
+ "version": "1.1.0-nightly.7",
4
4
  "description": "Harness-agnostic fleet of persistent, identity-bound AI agents. Declarative fleet.yaml, ACP sessions, supervision, and ours.network messaging.",
5
5
  "type": "module",
6
6
  "license": "FSL-1.1-Apache-2.0",