@aeolus-fleet/trierarch 0.18.0 → 0.20.0

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.
Files changed (76) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +11 -11
  3. package/dist/adapters/claude-code.d.ts +5 -3
  4. package/dist/adapters/claude-code.js +2 -0
  5. package/dist/adapters/claude-code.js.map +1 -1
  6. package/dist/adapters/codex.d.ts +5 -3
  7. package/dist/adapters/codex.js +2 -0
  8. package/dist/adapters/codex.js.map +1 -1
  9. package/dist/adapters/flags.d.ts +2 -2
  10. package/dist/adapters/flags.js +2 -2
  11. package/dist/adapters/git-workspace.js +2 -2
  12. package/dist/adapters/git-workspace.js.map +1 -1
  13. package/dist/adapters/harnesses.d.ts +6 -4
  14. package/dist/adapters/harnesses.js +11 -5
  15. package/dist/adapters/harnesses.js.map +1 -1
  16. package/dist/adapters/json-state.d.ts +6 -4
  17. package/dist/adapters/json-state.js +28 -23
  18. package/dist/adapters/json-state.js.map +1 -1
  19. package/dist/adapters/rest-fleet.d.ts +4 -3
  20. package/dist/adapters/rest-fleet.js +24 -13
  21. package/dist/adapters/rest-fleet.js.map +1 -1
  22. package/dist/adapters/service.js +1 -1
  23. package/dist/adapters/style.d.ts +3 -3
  24. package/dist/adapters/style.js +1 -2
  25. package/dist/adapters/style.js.map +1 -1
  26. package/dist/cli/config-check.d.ts +3 -3
  27. package/dist/cli/config-check.js +1 -1
  28. package/dist/cli/config-check.js.map +1 -1
  29. package/dist/cli/init.d.ts +2 -2
  30. package/dist/cli/init.js +1 -1
  31. package/dist/cli/init.js.map +1 -1
  32. package/dist/cli/list.d.ts +4 -3
  33. package/dist/cli/list.js +1 -1
  34. package/dist/cli/list.js.map +1 -1
  35. package/dist/cli/main.js +2 -2
  36. package/dist/cli/main.js.map +1 -1
  37. package/dist/cli/run.d.ts +12 -7
  38. package/dist/cli/run.js +53 -26
  39. package/dist/cli/run.js.map +1 -1
  40. package/dist/cli/status.d.ts +3 -2
  41. package/dist/cli/status.js +6 -5
  42. package/dist/cli/status.js.map +1 -1
  43. package/dist/core/check-settings.d.ts +25 -0
  44. package/dist/core/check-settings.js +52 -0
  45. package/dist/core/check-settings.js.map +1 -0
  46. package/dist/core/entry.d.ts +24 -29
  47. package/dist/core/entry.js +3 -1
  48. package/dist/core/entry.js.map +1 -1
  49. package/dist/core/handle-delivery.d.ts +9 -14
  50. package/dist/core/handle-delivery.js +4 -133
  51. package/dist/core/handle-delivery.js.map +1 -1
  52. package/dist/core/machine.d.ts +12 -0
  53. package/dist/core/machine.js +15 -0
  54. package/dist/core/machine.js.map +1 -0
  55. package/dist/core/options-schema.d.ts +7 -0
  56. package/dist/core/options-schema.js +10 -0
  57. package/dist/core/options-schema.js.map +1 -0
  58. package/dist/core/ports.d.ts +72 -9
  59. package/dist/core/reconciler.d.ts +50 -12
  60. package/dist/core/reconciler.js +129 -25
  61. package/dist/core/reconciler.js.map +1 -1
  62. package/dist/core/report-self.d.ts +16 -0
  63. package/dist/core/report-self.js +52 -0
  64. package/dist/core/report-self.js.map +1 -0
  65. package/dist/core/run-pass.d.ts +8 -7
  66. package/dist/core/run-pass.js +140 -70
  67. package/dist/core/run-pass.js.map +1 -1
  68. package/dist/index.d.ts +2 -2
  69. package/dist/index.js.map +1 -1
  70. package/package.json +7 -5
  71. package/dist/core/answers.d.ts +0 -4
  72. package/dist/core/answers.js +0 -32
  73. package/dist/core/answers.js.map +0 -1
  74. package/dist/core/check-want.d.ts +0 -32
  75. package/dist/core/check-want.js +0 -80
  76. package/dist/core/check-want.js.map +0 -1
@@ -0,0 +1,12 @@
1
+ import type { TrierarchReportDetails } from '@aeolus-fleet/common';
2
+ /** The machine as a trierarch reports it: its os and arch, each when it is a known one. */
3
+ export type Machine = NonNullable<TrierarchReportDetails['machine']>;
4
+ /**
5
+ * Policy: the machine a trierarch runs on, for the trierarch plugin to label
6
+ * its ship by (#102; docs/trierarch.md, "Machine labels"), from Node's
7
+ * platform and arch. One outside the known ones is left out.
8
+ */
9
+ export declare function machineOf(node: {
10
+ platform: string;
11
+ arch: string;
12
+ }): Machine;
@@ -0,0 +1,15 @@
1
+ /** Node's names for the platforms the trierarch plugin labels, by the os label's values. */
2
+ const OS_OF = { darwin: 'macos', linux: 'linux', win32: 'windows' };
3
+ /** Node's names for the architectures the trierarch plugin labels, by the arch label's values. */
4
+ const ARCH_OF = { arm64: 'arm64', x64: 'amd64' };
5
+ /**
6
+ * Policy: the machine a trierarch runs on, for the trierarch plugin to label
7
+ * its ship by (#102; docs/trierarch.md, "Machine labels"), from Node's
8
+ * platform and arch. One outside the known ones is left out.
9
+ */
10
+ export function machineOf(node) {
11
+ const os = OS_OF[node.platform];
12
+ const arch = ARCH_OF[node.arch];
13
+ return { ...(os === undefined ? {} : { os }), ...(arch === undefined ? {} : { arch }) };
14
+ }
15
+ //# sourceMappingURL=machine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine.js","sourceRoot":"","sources":["../../src/core/machine.ts"],"names":[],"mappings":"AAKA,4FAA4F;AAC5F,MAAM,KAAK,GAA0D,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AAE3H,kGAAkG;AAClG,MAAM,OAAO,GAA4D,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;AAE1G;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,IAAwC;IAChE,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChC,OAAO,EAAE,GAAG,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AAC1F,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { TrierarchConfiguration, TrierarchReportDetails } from '@aeolus-fleet/common';
2
+ /**
3
+ * A harness's options as a JSON Schema, as the trierarch's report details
4
+ * give it (docs/trierarch.md, "What a trierarch reports"): each option one of
5
+ * its value names, with its default when it has one.
6
+ */
7
+ export declare function optionsSchemaOf(harness: TrierarchConfiguration['harnesses'][string]): TrierarchReportDetails['harnesses'][number]['options'];
@@ -0,0 +1,10 @@
1
+ /**
2
+ * A harness's options as a JSON Schema, as the trierarch's report details
3
+ * give it (docs/trierarch.md, "What a trierarch reports"): each option one of
4
+ * its value names, with its default when it has one.
5
+ */
6
+ export function optionsSchemaOf(harness) {
7
+ const properties = Object.fromEntries(Object.entries(harness.options).map(([name, option]) => [name, { enum: Object.keys(option.values), ...(option.default !== undefined && { default: option.default }) }]));
8
+ return { type: 'object', properties, additionalProperties: false };
9
+ }
10
+ //# sourceMappingURL=options-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options-schema.js","sourceRoot":"","sources":["../../src/core/options-schema.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,OAAoD;IAClF,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CACnC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CACxK,CAAC;IACF,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAAC;AACrE,CAAC"}
@@ -1,5 +1,6 @@
1
- import type { ShipId, TrierarchAdapterFlag, TrierarchConfiguration, TrierarchWorkspace } from '@aeolus-fleet/common';
2
- import type { Outgoing, TrierarchState } from './entry.js';
1
+ import type { ClearOutcome, CrewStatus, ShipId, TrierarchConfiguration, TrierarchReportDetails, TrierarchWorkspace } from '@aeolus-fleet/common';
2
+ import type { TrierarchState } from './entry.js';
3
+ import type { Machine } from './machine.js';
3
4
  import type { Action } from './reconciler.js';
4
5
  /**
5
6
  * The trierarch's ports (docs/architecture.md, "The trierarch"). Adapters
@@ -7,7 +8,7 @@ import type { Action } from './reconciler.js';
7
8
  * and folders for workspaces, Claude Code for the harness, a JSON file for
8
9
  * state. Each throws only for a system failure.
9
10
  */
10
- /** Where a ship stands in the fleet, as `fleet.ship` answers the trierarch (fleet:crew). */
11
+ /** Where a ship stands in the fleet, as `fleet.ship` answers the trierarch (crew:run, for a ship assigned to it). */
11
12
  export type FleetShipStatus = {
12
13
  readonly kind: 'awaitingCrew';
13
14
  readonly name: string;
@@ -34,9 +35,43 @@ export type InboxAnswer = {
34
35
  } | {
35
36
  readonly kind: 'leaseEnded';
36
37
  };
38
+ /** A clear request to the trierarch's ship: the kept worktree, by the ship it belonged to and its repository. */
39
+ export interface ClearRequestToMe {
40
+ readonly shipId: ShipId;
41
+ readonly repository: string;
42
+ }
43
+ /** A crew request assigned to the trierarch's ship, as `fleet.assignedCrewRequests` answers: its settings unread. */
44
+ export interface AssignedRequest {
45
+ readonly shipId: ShipId;
46
+ readonly settings: unknown;
47
+ readonly settingsVersion: number;
48
+ /** How the trierarch last said the crew stands; releasing once the requester removed it; null until any. */
49
+ readonly status: CrewStatus | null;
50
+ }
51
+ /** A plain-text report to argo, the operator, stored once under its idempotency key. */
52
+ export interface ArgoReport {
53
+ readonly text: string;
54
+ readonly idempotencyKey: string;
55
+ }
56
+ /**
57
+ * The fleet as the trierarch's own ship calls it, with `crew:run`: it reaches
58
+ * only the ships whose crew requests are assigned to it (decision 0029).
59
+ */
60
+ /** A crew status as the trierarch writes it: the status, how many times it restarted the session within its window (0 on its first start), and when the session it runs now started, or null while none runs. */
61
+ export interface WrittenStatus {
62
+ readonly status: CrewStatus;
63
+ readonly attempt: number;
64
+ readonly startedAt: Date | null;
65
+ }
37
66
  export interface FleetPort {
38
67
  /** The fleet's URL, written into each session's identity. */
39
68
  readonly url: string;
69
+ /** The crew requests assigned to the trierarch's ship, oldest ship first. */
70
+ assignedRequests(): Promise<readonly AssignedRequest[]>;
71
+ /** Says how its crew of an assigned ship stands, with the restart attempt and when the session started (#332). */
72
+ writeStatus(shipId: ShipId, written: WrittenStatus): Promise<void>;
73
+ /** Confirms it released the ship of a releasing request, which then goes. */
74
+ confirmRelease(shipId: ShipId): Promise<void>;
40
75
  ship(shipId: ShipId): Promise<FleetShipStatus>;
41
76
  /** A new starting prompt's secret; the trierarch keeps it only until it registers. */
42
77
  getStartingPrompt(shipId: ShipId): Promise<{
@@ -52,7 +87,16 @@ export interface FleetPort {
52
87
  release(shipId: ShipId): Promise<void>;
53
88
  /** Acknowledges a delivery to the trierarch's own ship. */
54
89
  ack(deliveryId: string): Promise<void>;
55
- send(message: Outgoing): Promise<void>;
90
+ /** Answers a ping to the trierarch's own ship. */
91
+ pong(deliveryId: string): Promise<void>;
92
+ /** The pending clear requests to the trierarch's own ship, oldest first (decision 0032). */
93
+ pendingClears(): Promise<readonly ClearRequestToMe[]>;
94
+ /** Confirms a clear request: it removed the kept worktree, or keeps none; the request then goes. */
95
+ confirmCleared(cleared: ClearRequestToMe & {
96
+ outcome: ClearOutcome;
97
+ }): Promise<void>;
98
+ /** Sends argo a report, as the trierarch's own ship. */
99
+ reportToArgo(report: ArgoReport): Promise<void>;
56
100
  /** A session's inbox, asked with its crew token. */
57
101
  inbox(crewToken: string): Promise<InboxAnswer>;
58
102
  /** Reports on a ship's behalf, with its session's crew token. */
@@ -61,6 +105,14 @@ export interface FleetPort {
61
105
  state: 'blocked' | 'working';
62
106
  note: string;
63
107
  }): Promise<void>;
108
+ /** Reports as the trierarch's own ship: what it does, and its details. */
109
+ reportSelf(report: SelfReport): Promise<void>;
110
+ }
111
+ /** The trierarch's own report: idle or working, how many sessions run, and its details (docs/trierarch.md). */
112
+ export interface SelfReport {
113
+ readonly state: 'idle' | 'working';
114
+ readonly note: string;
115
+ readonly details: TrierarchReportDetails;
64
116
  }
65
117
  /** What a session's folder identity holds for the trierarch: written through the aeolus plugin, never a copy of it. */
66
118
  export interface Identity {
@@ -81,7 +133,7 @@ export interface HarnessPort {
81
133
  /** The crew token of the folder's identity, when there is one. */
82
134
  crewTokenOf(folder: string): Promise<string | undefined>;
83
135
  removeIdentity(folder: string): Promise<void>;
84
- /** Starts the harness in the folder: the first start with the want's first prompt, later ones continuing. */
136
+ /** Starts the harness in the folder: the first start with the settings' first prompt, later ones continuing. */
85
137
  launch(session: {
86
138
  shipId: ShipId;
87
139
  /** With the workspace, what the session is named after where the harness names one. */
@@ -108,9 +160,11 @@ export interface ProcessPort {
108
160
  list(): Promise<readonly ObservedSession[]>;
109
161
  stop(shipId: ShipId): Promise<void>;
110
162
  }
111
- /** A worktree under the trierarch's root, with the ship it is named after when it is one. */
163
+ /** A worktree under the trierarch's root (`<root>/<repository>/<name>`), with the ship it is named after when it is one. */
112
164
  export interface ObservedWorktree {
113
165
  readonly path: string;
166
+ readonly repository: string;
167
+ readonly name: string;
114
168
  readonly shipId?: ShipId;
115
169
  }
116
170
  export interface WorkspacePort {
@@ -137,7 +191,8 @@ export interface LoggedAction {
137
191
  readonly shipId: ShipId;
138
192
  /** Known once the ship was first crewed. */
139
193
  readonly shipName?: string;
140
- readonly action: Exclude<Action['kind'], 'notify'>;
194
+ /** What the loop did for the ship: an action it carried out, or leave when another session crews the ship. */
195
+ readonly action: Exclude<Action['kind'], 'argo' | 'status' | 'refuse'> | 'leave';
141
196
  readonly outcome: string;
142
197
  /** For a failure: what happens next, and where to look. */
143
198
  readonly next?: string;
@@ -146,9 +201,17 @@ export interface Logger {
146
201
  warn(message: string): void;
147
202
  action(logged: LoggedAction): void;
148
203
  }
149
- /** What describe answers beside the configuration: the trierarch's version, and the flags each harness's adapter adds itself. */
204
+ /** A flag a harness adapter adds itself, as mechanism, never the operator's: on every launch or on a restart only. */
205
+ export interface AdapterFlag {
206
+ readonly flag: string;
207
+ readonly when: 'always' | 'restart';
208
+ }
209
+ /** The trierarch's configuration, its version, the flags each harness's adapter adds itself, and those its adapter calls risky. */
150
210
  export interface TrierarchSetup {
151
211
  readonly configuration: TrierarchConfiguration;
152
212
  readonly version: string;
153
- readonly adapterFlags: Readonly<Record<string, readonly TrierarchAdapterFlag[]>>;
213
+ readonly adapterFlags: Readonly<Record<string, readonly AdapterFlag[]>>;
214
+ readonly riskyFlags: Readonly<Record<string, readonly string[]>>;
215
+ /** The machine it runs on, by os and arch, for the trierarch plugin's labels (#102); none reports none. */
216
+ readonly machine?: Machine;
154
217
  }
@@ -1,11 +1,13 @@
1
- import type { ShipId, TrierarchConfiguration } from '@aeolus-fleet/common';
2
- import { type Outgoing, type TrierarchState } from './entry.js';
3
- import type { InboxAnswer, ObservedSession, ObservedWorktree, Turn } from './ports.js';
1
+ import type { CrewStatus, ShipId, TrierarchConfiguration } from '@aeolus-fleet/common';
2
+ import { type Refusal } from './check-settings.js';
3
+ import { type Entry, type KeptWorktree, type TrierarchState } from './entry.js';
4
+ import type { ArgoReport, AssignedRequest, ClearRequestToMe, InboxAnswer, ObservedSession, ObservedWorktree, Turn, WrittenStatus } from './ports.js';
4
5
  /**
5
6
  * The Reconciler (docs/architecture.md, "The trierarch"): a pure function
6
- * from the wanted list, what runs and the time to the actions that make them
7
- * match, and the state those actions start from. It is the only place that
8
- * decides; the run pass only carries the actions out.
7
+ * from the crew requests assigned to the trierarch, its saved state, what
8
+ * runs and the time to the actions that make them match, and the state those
9
+ * actions start from. It is the only place that decides; the run pass only
10
+ * carries the actions out.
9
11
  */
10
12
  /** What the trierarch saw this pass. */
11
13
  export interface Observed {
@@ -18,7 +20,7 @@ export interface Observed {
18
20
  }>>;
19
21
  }
20
22
  export type Action =
21
- /** Crew the ship: starting prompt, register, workspace, identity, launch. Resumed when a stop mid-crew left it crewing. */
23
+ /** Crew the ship: starting prompt, register, workspace, identity, launch. Resumed while its own lease may still hold the ship. */
22
24
  {
23
25
  readonly kind: 'crew';
24
26
  readonly shipId: ShipId;
@@ -35,24 +37,48 @@ export type Action =
35
37
  readonly kind: 'wake';
36
38
  readonly shipId: ShipId;
37
39
  }
38
- /** Release asked by a message: stop, end the lease, the workspace, answer released. */
40
+ /** Its request was removed: stop, end the lease, the workspace, then confirm. */
39
41
  | {
40
42
  readonly kind: 'release';
41
43
  readonly shipId: ShipId;
42
44
  }
43
- /** The lease ended elsewhere (released, re-crewed or retired): stop, the workspace, notify leaseEnded. */
45
+ /** A removed request it does not crew: confirm alone. */
44
46
  | {
45
- readonly kind: 'drop';
47
+ readonly kind: 'confirm';
46
48
  readonly shipId: ShipId;
49
+ }
50
+ /** Its request is no longer assigned here: stop, remove the identity of the entry it was; the worktree stays as an orphan. */
51
+ | {
52
+ readonly kind: 'forget';
53
+ readonly shipId: ShipId;
54
+ readonly entry: Entry;
47
55
  } | {
48
- readonly kind: 'notify';
49
- readonly message: Outgoing;
56
+ readonly kind: 'status';
57
+ readonly shipId: ShipId;
58
+ readonly written: WrittenStatus;
50
59
  }
51
60
  /** Report on the ship's behalf, with its session's crew token. */
52
61
  | {
53
62
  readonly kind: 'report';
54
63
  readonly shipId: ShipId;
55
64
  readonly note: string;
65
+ }
66
+ /** Tell argo it cannot crew this settings version. */
67
+ | {
68
+ readonly kind: 'refuse';
69
+ readonly shipId: ShipId;
70
+ readonly settingsVersion: number;
71
+ readonly refusal: Refusal;
72
+ } | {
73
+ readonly kind: 'argo';
74
+ readonly report: ArgoReport;
75
+ }
76
+ /** A clear request (decision 0032): remove the kept worktree it names, or, when none is kept, confirm alone. */
77
+ | {
78
+ readonly kind: 'clear';
79
+ readonly shipId: ShipId;
80
+ readonly repository: string;
81
+ readonly kept?: KeptWorktree;
56
82
  };
57
83
  export interface Reconciled {
58
84
  readonly state: TrierarchState;
@@ -60,8 +86,20 @@ export interface Reconciled {
60
86
  }
61
87
  /** What reconciling needs beside the state and what was seen. */
62
88
  export interface ReconcileContext {
89
+ readonly requests: readonly AssignedRequest[];
90
+ /** The pending clear requests to the trierarch's ship. */
91
+ readonly clears: readonly ClearRequestToMe[];
63
92
  readonly observed: Observed;
64
93
  readonly now: Date;
65
94
  readonly configuration: TrierarchConfiguration;
66
95
  }
67
96
  export declare function reconcile(state: TrierarchState, context: ReconcileContext): Reconciled;
97
+ /**
98
+ * The status an entry writes (#332): its state; the restart attempt, the
99
+ * restarts made or under way within the window (a crashed entry's last exit
100
+ * started none); and when the session it runs now started, the time it took
101
+ * running, or null while none runs.
102
+ */
103
+ export declare function writtenStatusOf(entry: Entry & {
104
+ state: CrewStatus;
105
+ }): WrittenStatus;
@@ -1,44 +1,143 @@
1
- import { putEntry, withState } from './entry.js';
1
+ import { checkSettings } from './check-settings.js';
2
+ import { putEntry, removeEntry, withState } from './entry.js';
2
3
  import { decideRestart, exitsInWindow } from './restart-policy.js';
3
4
  const RESTARTING_NOTE = 'blocked: session crashed, restarting';
4
5
  const CRASHED_NOTE = 'blocked: session crashed, restart budget spent';
6
+ /** The statuses the reconciler writes; crewing and running at the first crew are the crew's own to write. */
7
+ const WRITTEN = new Set(['running', 'restarting', 'crashed']);
8
+ const NOTHING = { actions: [], starts: 0 };
5
9
  export function reconcile(state, context) {
6
- const { observed, configuration } = context;
7
- let next = state;
10
+ const { observed, configuration, requests, now } = context;
11
+ const requested = new Map(requests.map((request) => [request.shipId, request]));
12
+ const assigned = new Set(requested.keys());
13
+ let next = { ...state, refused: Object.fromEntries(Object.entries(state.refused).filter(([shipId]) => assigned.has(shipId))) };
8
14
  const actions = [];
9
15
  let running = observed.sessions.filter((session) => session.status === 'running' && session.shipId in state.entries).length;
10
16
  const canStart = () => running < configuration.caps.running;
11
17
  for (const entry of Object.values(state.entries)) {
12
- const step = stepOf(entry, { ...context, canStart: canStart() });
18
+ const request = requested.get(entry.shipId);
19
+ if (request === undefined) {
20
+ next = removeEntry(next, entry.shipId);
21
+ actions.push({ kind: 'forget', shipId: entry.shipId, entry });
22
+ continue;
23
+ }
24
+ if (request.status === 'releasing') {
25
+ actions.push({ kind: 'release', shipId: entry.shipId });
26
+ continue;
27
+ }
28
+ const step = request.settingsVersion === entry.settingsVersion ? stepOf(entry, { ...context, canStart: canStart() }) : newVersionStep(entry, { request, state: next, context });
29
+ const after = step.entry ?? entry;
13
30
  next = step.entry === undefined ? next : putEntry(next, step.entry);
14
31
  actions.push(...step.actions);
32
+ if (WRITTEN.has(after.state) && request.status !== after.state && after.state !== 'releasing') {
33
+ actions.push({ kind: 'status', shipId: entry.shipId, written: writtenStatusOf(after) });
34
+ }
15
35
  running += step.starts;
16
36
  }
37
+ for (const request of requests) {
38
+ if (request.shipId in state.entries) {
39
+ continue;
40
+ }
41
+ if (request.status === 'releasing') {
42
+ actions.push({ kind: 'confirm', shipId: request.shipId });
43
+ continue;
44
+ }
45
+ const checked = checkSettings(request.settings, { shipId: request.shipId, configuration, state: next });
46
+ if (!checked.isOk) {
47
+ if (next.refused[request.shipId] !== request.settingsVersion) {
48
+ actions.push({ kind: 'refuse', shipId: request.shipId, settingsVersion: request.settingsVersion, refusal: checked.error });
49
+ }
50
+ continue;
51
+ }
52
+ if (canStart()) {
53
+ next = putEntry(next, entryOf(checked.value, { shipId: request.shipId, settingsVersion: request.settingsVersion, now }));
54
+ actions.push({ kind: 'crew', shipId: request.shipId, isResumed: false });
55
+ running += 1;
56
+ }
57
+ }
17
58
  for (const session of observed.sessions) {
18
59
  if (!(session.shipId in state.entries)) {
19
60
  actions.push({ kind: 'stop', shipId: session.shipId });
20
61
  }
21
62
  }
22
- const known = new Set([...Object.values(state.entries).flatMap((entry) => (entry.folder === undefined ? [] : [entry.folder])), ...state.kept.map((kept) => kept.path)]);
63
+ // A kept worktree stays until it is gone from disk, as when a human removed it (#325). One an entry
64
+ // works in again is that entry's worktree, no longer kept, so a clear never removes it (decision 0032).
65
+ const onDisk = new Set(observed.worktrees.map((worktree) => worktree.path));
66
+ const inUse = new Set(Object.values(next.entries).flatMap((entry) => (entry.folder === undefined ? [] : [entry.folder])));
67
+ const kept = next.kept.filter((each) => onDisk.has(each.path) && !inUse.has(each.path));
68
+ const known = new Set([...inUse, ...kept.map((each) => each.path)]);
23
69
  const orphans = observed.worktrees
24
- .filter((worktree) => !known.has(worktree.path) && (worktree.shipId === undefined || !(worktree.shipId in state.entries)))
25
- .map((worktree) => worktree.path);
26
- return { state: { ...next, orphans }, actions };
70
+ .filter((worktree) => !known.has(worktree.path) && (worktree.shipId === undefined || !(worktree.shipId in next.entries)))
71
+ .map(({ path, repository, name }) => ({ path, repository, name }));
72
+ // A clear request removes only a worktree this trierarch kept; for any other it keeps none (decision 0032).
73
+ for (const { shipId, repository } of context.clears) {
74
+ const held = kept.find((each) => each.shipId === shipId && each.repository === repository);
75
+ actions.push({ kind: 'clear', shipId, repository, ...(held !== undefined && { kept: held }) });
76
+ }
77
+ return { state: { ...next, kept, orphans }, actions };
78
+ }
79
+ /**
80
+ * The status an entry writes (#332): its state; the restart attempt, the
81
+ * restarts made or under way within the window (a crashed entry's last exit
82
+ * started none); and when the session it runs now started, the time it took
83
+ * running, or null while none runs.
84
+ */
85
+ export function writtenStatusOf(entry) {
86
+ const attempt = entry.state === 'crashed' ? Math.max(0, entry.exits.length - 1) : entry.exits.length;
87
+ return { status: entry.state, attempt, startedAt: entry.state === 'running' ? new Date(entry.since) : null };
88
+ }
89
+ /** A new entry, crewing since now, for checked settings of a version. */
90
+ function entryOf(checked, at) {
91
+ const { settings, options } = checked;
92
+ return {
93
+ shipId: at.shipId,
94
+ settingsVersion: at.settingsVersion,
95
+ harness: settings.harness,
96
+ workspace: settings.workspace,
97
+ ...(settings.squadron !== undefined && { squadron: settings.squadron }),
98
+ ...(settings.firstPrompt !== undefined && { firstPrompt: settings.firstPrompt }),
99
+ options,
100
+ state: 'crewing',
101
+ since: at.now.toISOString(),
102
+ exits: [],
103
+ hasStarted: false,
104
+ wake: { waiting: 0, isPending: false },
105
+ };
106
+ }
107
+ /**
108
+ * A new settings version of a request it crews (Restart or Edit): the
109
+ * session stops and the ship is crewed again with that version, in its
110
+ * folder, with a fresh restart budget. It is no release: the worktree stays.
111
+ * Settings this trierarch cannot crew are refused to argo, and the entry
112
+ * stays as it was.
113
+ */
114
+ function newVersionStep(entry, at) {
115
+ const { request, state, context } = at;
116
+ const checked = checkSettings(request.settings, { shipId: entry.shipId, configuration: context.configuration, state });
117
+ if (!checked.isOk) {
118
+ const step = stepOf(entry, { ...context, canStart: false });
119
+ return state.refused[entry.shipId] === request.settingsVersion
120
+ ? step
121
+ : { ...step, actions: [...step.actions, { kind: 'refuse', shipId: entry.shipId, settingsVersion: request.settingsVersion, refusal: checked.error }] };
122
+ }
123
+ const fresh = entryOf(checked.value, { shipId: entry.shipId, settingsVersion: request.settingsVersion, now: context.now });
124
+ return {
125
+ entry: { ...fresh, hasStarted: entry.hasStarted, ...(entry.shipName !== undefined && { shipName: entry.shipName }), ...(entry.folder !== undefined && { folder: entry.folder }) },
126
+ actions: [
127
+ { kind: 'stop', shipId: entry.shipId },
128
+ { kind: 'crew', shipId: entry.shipId, isResumed: true },
129
+ ],
130
+ starts: 0,
131
+ };
27
132
  }
28
133
  function stepOf(entry, context) {
29
134
  const { observed, now, canStart } = context;
30
135
  const seen = observed.ships[entry.shipId];
31
- if (entry.state === 'releasing') {
32
- return { actions: [{ kind: 'release', shipId: entry.shipId }], starts: 0 };
33
- }
34
136
  if (seen?.inbox.kind === 'leaseEnded') {
35
- return { actions: [{ kind: 'drop', shipId: entry.shipId }], starts: 0 };
137
+ // Released elsewhere (row 11): its session stops and the ship is crewed again, in its folder.
138
+ return { entry: withState(entry, { state: 'crewing', now }), actions: [{ kind: 'stop', shipId: entry.shipId }, { kind: 'crew', shipId: entry.shipId, isResumed: false }], starts: 0 };
36
139
  }
37
140
  switch (entry.state) {
38
- case 'wanted':
39
- return canStart
40
- ? { entry: withState(entry, { state: 'crewing', now }), actions: [{ kind: 'crew', shipId: entry.shipId, isResumed: false }], starts: 1 }
41
- : { actions: [], starts: 0 };
42
141
  case 'crewing':
43
142
  return { actions: [{ kind: 'crew', shipId: entry.shipId, isResumed: true }], starts: 1 };
44
143
  case 'running':
@@ -46,9 +145,10 @@ function stepOf(entry, context) {
46
145
  case 'restarting':
47
146
  return entry.restartAt !== undefined && now >= new Date(entry.restartAt) && canStart
48
147
  ? { entry: withState(entry, { state: 'running', now }), actions: [{ kind: 'launch', shipId: entry.shipId }], starts: 1 }
49
- : { actions: [], starts: 0 };
148
+ : NOTHING;
50
149
  case 'crashed':
51
- return { actions: [], starts: 0 };
150
+ case 'releasing':
151
+ return NOTHING;
52
152
  }
53
153
  }
54
154
  function runningStep(entry, context) {
@@ -56,7 +156,7 @@ function runningStep(entry, context) {
56
156
  const session = observed.sessions.find((each) => each.shipId === entry.shipId);
57
157
  if (session === undefined) {
58
158
  // No session at all, as after the machine restarts: start it again, with no restart counted.
59
- return canStart ? { actions: [{ kind: 'launch', shipId: entry.shipId }], starts: 1 } : { actions: [], starts: 0 };
159
+ return canStart ? { actions: [{ kind: 'launch', shipId: entry.shipId }], starts: 1 } : NOTHING;
60
160
  }
61
161
  if (session.status === 'exited') {
62
162
  const exits = [...exitsInWindow(entry.exits, now), now.toISOString()];
@@ -74,10 +174,7 @@ function runningStep(entry, context) {
74
174
  actions: [
75
175
  { kind: 'stop', shipId: entry.shipId },
76
176
  { kind: 'report', shipId: entry.shipId, note: CRASHED_NOTE },
77
- {
78
- kind: 'notify',
79
- message: { to: entry.requester, name: 'crashed', payload: { shipId: entry.shipId, exits: exits.length }, idempotencyKey: `trierarch:crashed:${entry.shipId}:${now.toISOString()}` },
80
- },
177
+ { kind: 'argo', report: crashReport(entry, { exits: exits.length, now }) },
81
178
  ],
82
179
  starts: 0,
83
180
  };
@@ -85,10 +182,17 @@ function runningStep(entry, context) {
85
182
  }
86
183
  return wakeStep(entry, observed.ships[entry.shipId]);
87
184
  }
185
+ /** What argo is told when a session's restart budget is spent: a human decides. */
186
+ function crashReport(entry, at) {
187
+ return {
188
+ text: `${entry.shipName ?? entry.shipId} (${entry.shipId}): its session crashed ${String(at.exits)} times within an hour, restart budget spent; status crashed. Restart it in the console to crew it again.`,
189
+ idempotencyKey: `trierarch:crashed:${entry.shipId}:${at.now.toISOString()}`,
190
+ };
191
+ }
88
192
  /** One wake per rise in the waiting count, given once the session is idle, and nothing more until it has received. */
89
193
  function wakeStep(entry, seen) {
90
194
  if (seen?.inbox.kind !== 'waiting') {
91
- return { actions: [], starts: 0 };
195
+ return NOTHING;
92
196
  }
93
197
  const { count } = seen.inbox;
94
198
  const isPending = count === 0 ? false : entry.wake.isPending || count > entry.wake.waiting;
@@ -96,6 +200,6 @@ function wakeStep(entry, seen) {
96
200
  return { entry: { ...entry, wake: { waiting: count, isPending: false } }, actions: [{ kind: 'wake', shipId: entry.shipId }], starts: 0 };
97
201
  }
98
202
  const wake = { waiting: count, isPending };
99
- return wake.waiting === entry.wake.waiting && wake.isPending === entry.wake.isPending ? { actions: [], starts: 0 } : { entry: { ...entry, wake }, actions: [], starts: 0 };
203
+ return wake.waiting === entry.wake.waiting && wake.isPending === entry.wake.isPending ? NOTHING : { entry: { ...entry, wake }, actions: [], starts: 0 };
100
204
  }
101
205
  //# sourceMappingURL=reconciler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"reconciler.js","sourceRoot":"","sources":["../../src/core/reconciler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reconciler.js","sourceRoot":"","sources":["../../src/core/reconciler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { FleetPort, ProcessPort, StatePort, TrierarchSetup } from './ports.js';
2
+ /** Reports the trierarch's own ship when something changed; the first call, at start, always reports. */
3
+ export type ReportSelf = () => Promise<void>;
4
+ /**
5
+ * Use case: the trierarch reports as its own ship (docs/trierarch.md, "What
6
+ * a trierarch reports"): working while a session runs, idle with none, a
7
+ * note saying how many run of its cap and how many crashed, and its details
8
+ * from its configuration and saved state. It reports on start, then only
9
+ * when the report would differ from the last one it sent.
10
+ */
11
+ export declare function createReportSelf(deps: {
12
+ fleet: FleetPort;
13
+ processes: ProcessPort;
14
+ state: StatePort;
15
+ setup: TrierarchSetup;
16
+ }): ReportSelf;
@@ -0,0 +1,52 @@
1
+ import { optionsSchemaOf } from './options-schema.js';
2
+ /**
3
+ * Use case: the trierarch reports as its own ship (docs/trierarch.md, "What
4
+ * a trierarch reports"): working while a session runs, idle with none, a
5
+ * note saying how many run of its cap and how many crashed, and its details
6
+ * from its configuration and saved state. It reports on start, then only
7
+ * when the report would differ from the last one it sent.
8
+ */
9
+ export function createReportSelf(deps) {
10
+ let lastSent;
11
+ return async () => {
12
+ const state = await deps.state.load();
13
+ const running = (await deps.processes.list()).filter((session) => session.status === 'running').length;
14
+ const report = selfReportOf({ setup: deps.setup, state, running });
15
+ const sent = JSON.stringify(report);
16
+ if (sent === lastSent) {
17
+ return;
18
+ }
19
+ await deps.fleet.reportSelf(report);
20
+ lastSent = sent;
21
+ };
22
+ }
23
+ function selfReportOf(at) {
24
+ const { setup, state, running } = at;
25
+ const crashed = Object.values(state.entries).filter((entry) => entry.state === 'crashed').length;
26
+ const note = `${String(running)} of ${String(setup.configuration.caps.ships)} running${crashed > 0 ? `, ${String(crashed)} crashed` : ''}`;
27
+ return { state: running > 0 ? 'working' : 'idle', note, details: detailsOf(setup, state) };
28
+ }
29
+ /** A flag's name, without a value given with `=`. */
30
+ function flagName(flag) {
31
+ return flag.split('=', 1)[0] ?? flag;
32
+ }
33
+ /** The trierarch's report details: what it offers from its configuration, the worktrees it kept and found, its version. */
34
+ function detailsOf(setup, state) {
35
+ const { configuration, version } = setup;
36
+ return {
37
+ harnesses: Object.entries(configuration.harnesses).map(([harness, settings]) => ({
38
+ harness,
39
+ options: optionsSchemaOf(settings),
40
+ flags: [...settings.flags],
41
+ riskyFlags: settings.flags.filter((flag) => setup.riskyFlags[harness]?.includes(flagName(flag)) === true),
42
+ })),
43
+ workspaces: { repositories: Object.keys(configuration.repositories), folders: Object.keys(configuration.folders) },
44
+ caps: configuration.caps,
45
+ // Paths stay on the machine: names only (decision 0032).
46
+ kept: state.kept.map(({ shipId, repository }) => ({ shipId, repository })),
47
+ orphans: state.orphans.map(({ repository, name }) => ({ repository, name })),
48
+ ...(setup.machine === undefined || Object.keys(setup.machine).length === 0 ? {} : { machine: setup.machine }),
49
+ version,
50
+ };
51
+ }
52
+ //# sourceMappingURL=report-self.js.map