@aeolus-fleet/trierarch 0.17.3 → 0.19.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 (88) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +18 -16
  3. package/dist/adapters/claude-code.d.ts +11 -1
  4. package/dist/adapters/claude-code.js +32 -10
  5. package/dist/adapters/claude-code.js.map +1 -1
  6. package/dist/adapters/codex.d.ts +10 -1
  7. package/dist/adapters/codex.js +15 -4
  8. package/dist/adapters/codex.js.map +1 -1
  9. package/dist/adapters/command-line.d.ts +15 -0
  10. package/dist/adapters/command-line.js +17 -0
  11. package/dist/adapters/command-line.js.map +1 -0
  12. package/dist/adapters/files.d.ts +9 -0
  13. package/dist/adapters/files.js +16 -0
  14. package/dist/adapters/files.js.map +1 -1
  15. package/dist/adapters/flags.d.ts +2 -2
  16. package/dist/adapters/flags.js +2 -2
  17. package/dist/adapters/git-workspace.js +1 -1
  18. package/dist/adapters/harnesses.d.ts +10 -2
  19. package/dist/adapters/harnesses.js +26 -3
  20. package/dist/adapters/harnesses.js.map +1 -1
  21. package/dist/adapters/json-state.d.ts +6 -4
  22. package/dist/adapters/json-state.js +21 -21
  23. package/dist/adapters/json-state.js.map +1 -1
  24. package/dist/adapters/log.d.ts +39 -0
  25. package/dist/adapters/log.js +65 -0
  26. package/dist/adapters/log.js.map +1 -0
  27. package/dist/adapters/paths.d.ts +1 -0
  28. package/dist/adapters/paths.js +1 -0
  29. package/dist/adapters/paths.js.map +1 -1
  30. package/dist/adapters/rest-fleet.d.ts +4 -3
  31. package/dist/adapters/rest-fleet.js +38 -18
  32. package/dist/adapters/rest-fleet.js.map +1 -1
  33. package/dist/adapters/service.js +18 -15
  34. package/dist/adapters/service.js.map +1 -1
  35. package/dist/adapters/style.d.ts +18 -0
  36. package/dist/adapters/style.js +38 -0
  37. package/dist/adapters/style.js.map +1 -0
  38. package/dist/cli/config-check.d.ts +11 -2
  39. package/dist/cli/config-check.js +26 -5
  40. package/dist/cli/config-check.js.map +1 -1
  41. package/dist/cli/init.d.ts +2 -2
  42. package/dist/cli/init.js +41 -15
  43. package/dist/cli/init.js.map +1 -1
  44. package/dist/cli/list.d.ts +7 -4
  45. package/dist/cli/list.js +18 -8
  46. package/dist/cli/list.js.map +1 -1
  47. package/dist/cli/main.js +33 -16
  48. package/dist/cli/main.js.map +1 -1
  49. package/dist/cli/prompter.d.ts +4 -0
  50. package/dist/cli/prompter.js +18 -3
  51. package/dist/cli/prompter.js.map +1 -1
  52. package/dist/cli/run.d.ts +13 -8
  53. package/dist/cli/run.js +48 -27
  54. package/dist/cli/run.js.map +1 -1
  55. package/dist/cli/status.d.ts +13 -4
  56. package/dist/cli/status.js +43 -17
  57. package/dist/cli/status.js.map +1 -1
  58. package/dist/core/check-settings.d.ts +25 -0
  59. package/dist/core/check-settings.js +52 -0
  60. package/dist/core/check-settings.js.map +1 -0
  61. package/dist/core/entry.d.ts +18 -30
  62. package/dist/core/entry.js +3 -1
  63. package/dist/core/entry.js.map +1 -1
  64. package/dist/core/handle-delivery.d.ts +9 -14
  65. package/dist/core/handle-delivery.js +4 -133
  66. package/dist/core/handle-delivery.js.map +1 -1
  67. package/dist/core/options-schema.d.ts +7 -0
  68. package/dist/core/options-schema.js +10 -0
  69. package/dist/core/options-schema.js.map +1 -0
  70. package/dist/core/ports.d.ts +60 -6
  71. package/dist/core/reconciler.d.ts +32 -12
  72. package/dist/core/reconciler.js +107 -23
  73. package/dist/core/reconciler.js.map +1 -1
  74. package/dist/core/report-self.d.ts +16 -0
  75. package/dist/core/report-self.js +41 -0
  76. package/dist/core/report-self.js.map +1 -0
  77. package/dist/core/run-pass.d.ts +8 -4
  78. package/dist/core/run-pass.js +135 -56
  79. package/dist/core/run-pass.js.map +1 -1
  80. package/dist/index.d.ts +2 -2
  81. package/dist/index.js.map +1 -1
  82. package/package.json +7 -5
  83. package/dist/core/answers.d.ts +0 -4
  84. package/dist/core/answers.js +0 -27
  85. package/dist/core/answers.js.map +0 -1
  86. package/dist/core/check-want.d.ts +0 -32
  87. package/dist/core/check-want.js +0 -80
  88. package/dist/core/check-want.js.map +0 -1
@@ -1,44 +1,123 @@
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, status: after.state });
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
+ const known = new Set([...Object.values(next.entries).flatMap((entry) => (entry.folder === undefined ? [] : [entry.folder])), ...next.kept.map((kept) => kept.path)]);
23
64
  const orphans = observed.worktrees
24
- .filter((worktree) => !known.has(worktree.path) && (worktree.shipId === undefined || !(worktree.shipId in state.entries)))
65
+ .filter((worktree) => !known.has(worktree.path) && (worktree.shipId === undefined || !(worktree.shipId in next.entries)))
25
66
  .map((worktree) => worktree.path);
26
67
  return { state: { ...next, orphans }, actions };
27
68
  }
69
+ /** A new entry, crewing since now, for checked settings of a version. */
70
+ function entryOf(checked, at) {
71
+ const { settings, options } = checked;
72
+ return {
73
+ shipId: at.shipId,
74
+ settingsVersion: at.settingsVersion,
75
+ harness: settings.harness,
76
+ workspace: settings.workspace,
77
+ ...(settings.squadron !== undefined && { squadron: settings.squadron }),
78
+ ...(settings.firstPrompt !== undefined && { firstPrompt: settings.firstPrompt }),
79
+ options,
80
+ state: 'crewing',
81
+ since: at.now.toISOString(),
82
+ exits: [],
83
+ hasStarted: false,
84
+ wake: { waiting: 0, isPending: false },
85
+ };
86
+ }
87
+ /**
88
+ * A new settings version of a request it crews (Restart or Edit): the
89
+ * session stops and the ship is crewed again with that version, in its
90
+ * folder, with a fresh restart budget. It is no release: the worktree stays.
91
+ * Settings this trierarch cannot crew are refused to argo, and the entry
92
+ * stays as it was.
93
+ */
94
+ function newVersionStep(entry, at) {
95
+ const { request, state, context } = at;
96
+ const checked = checkSettings(request.settings, { shipId: entry.shipId, configuration: context.configuration, state });
97
+ if (!checked.isOk) {
98
+ const step = stepOf(entry, { ...context, canStart: false });
99
+ return state.refused[entry.shipId] === request.settingsVersion
100
+ ? step
101
+ : { ...step, actions: [...step.actions, { kind: 'refuse', shipId: entry.shipId, settingsVersion: request.settingsVersion, refusal: checked.error }] };
102
+ }
103
+ const fresh = entryOf(checked.value, { shipId: entry.shipId, settingsVersion: request.settingsVersion, now: context.now });
104
+ return {
105
+ entry: { ...fresh, hasStarted: entry.hasStarted, ...(entry.shipName !== undefined && { shipName: entry.shipName }), ...(entry.folder !== undefined && { folder: entry.folder }) },
106
+ actions: [
107
+ { kind: 'stop', shipId: entry.shipId },
108
+ { kind: 'crew', shipId: entry.shipId, isResumed: true },
109
+ ],
110
+ starts: 0,
111
+ };
112
+ }
28
113
  function stepOf(entry, context) {
29
114
  const { observed, now, canStart } = context;
30
115
  const seen = observed.ships[entry.shipId];
31
- if (entry.state === 'releasing') {
32
- return { actions: [{ kind: 'release', shipId: entry.shipId }], starts: 0 };
33
- }
34
116
  if (seen?.inbox.kind === 'leaseEnded') {
35
- return { actions: [{ kind: 'drop', shipId: entry.shipId }], starts: 0 };
117
+ // Released elsewhere (row 11): its session stops and the ship is crewed again, in its folder.
118
+ return { entry: withState(entry, { state: 'crewing', now }), actions: [{ kind: 'stop', shipId: entry.shipId }, { kind: 'crew', shipId: entry.shipId, isResumed: false }], starts: 0 };
36
119
  }
37
120
  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
121
  case 'crewing':
43
122
  return { actions: [{ kind: 'crew', shipId: entry.shipId, isResumed: true }], starts: 1 };
44
123
  case 'running':
@@ -46,9 +125,10 @@ function stepOf(entry, context) {
46
125
  case 'restarting':
47
126
  return entry.restartAt !== undefined && now >= new Date(entry.restartAt) && canStart
48
127
  ? { entry: withState(entry, { state: 'running', now }), actions: [{ kind: 'launch', shipId: entry.shipId }], starts: 1 }
49
- : { actions: [], starts: 0 };
128
+ : NOTHING;
50
129
  case 'crashed':
51
- return { actions: [], starts: 0 };
130
+ case 'releasing':
131
+ return NOTHING;
52
132
  }
53
133
  }
54
134
  function runningStep(entry, context) {
@@ -56,7 +136,7 @@ function runningStep(entry, context) {
56
136
  const session = observed.sessions.find((each) => each.shipId === entry.shipId);
57
137
  if (session === undefined) {
58
138
  // 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 };
139
+ return canStart ? { actions: [{ kind: 'launch', shipId: entry.shipId }], starts: 1 } : NOTHING;
60
140
  }
61
141
  if (session.status === 'exited') {
62
142
  const exits = [...exitsInWindow(entry.exits, now), now.toISOString()];
@@ -74,10 +154,7 @@ function runningStep(entry, context) {
74
154
  actions: [
75
155
  { kind: 'stop', shipId: entry.shipId },
76
156
  { 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
- },
157
+ { kind: 'argo', report: crashReport(entry, { exits: exits.length, now }) },
81
158
  ],
82
159
  starts: 0,
83
160
  };
@@ -85,10 +162,17 @@ function runningStep(entry, context) {
85
162
  }
86
163
  return wakeStep(entry, observed.ships[entry.shipId]);
87
164
  }
165
+ /** What argo is told when a session's restart budget is spent: a human decides. */
166
+ function crashReport(entry, at) {
167
+ return {
168
+ 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.`,
169
+ idempotencyKey: `trierarch:crashed:${entry.shipId}:${at.now.toISOString()}`,
170
+ };
171
+ }
88
172
  /** One wake per rise in the waiting count, given once the session is idle, and nothing more until it has received. */
89
173
  function wakeStep(entry, seen) {
90
174
  if (seen?.inbox.kind !== 'waiting') {
91
- return { actions: [], starts: 0 };
175
+ return NOTHING;
92
176
  }
93
177
  const { count } = seen.inbox;
94
178
  const isPending = count === 0 ? false : entry.wake.isPending || count > entry.wake.waiting;
@@ -96,6 +180,6 @@ function wakeStep(entry, seen) {
96
180
  return { entry: { ...entry, wake: { waiting: count, isPending: false } }, actions: [{ kind: 'wake', shipId: entry.shipId }], starts: 0 };
97
181
  }
98
182
  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 };
183
+ return wake.waiting === entry.wake.waiting && wake.isPending === entry.wake.isPending ? NOTHING : { entry: { ...entry, wake }, actions: [], starts: 0 };
100
184
  }
101
185
  //# 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,41 @@
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
+ /** The trierarch's report details: what it offers from its configuration, the worktrees it kept and found, its version. */
30
+ function detailsOf(setup, state) {
31
+ const { configuration, version } = setup;
32
+ return {
33
+ harnesses: Object.entries(configuration.harnesses).map(([harness, settings]) => ({ harness, options: optionsSchemaOf(settings), flags: [...settings.flags] })),
34
+ workspaces: { repositories: Object.keys(configuration.repositories), folders: Object.keys(configuration.folders) },
35
+ caps: configuration.caps,
36
+ kept: state.kept.map(({ shipId, path }) => ({ shipId, path })),
37
+ orphans: state.orphans.map((path) => ({ path })),
38
+ version,
39
+ };
40
+ }
41
+ //# sourceMappingURL=report-self.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report-self.js","sourceRoot":"","sources":["../../src/core/report-self.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,14 @@
1
1
  import type { FleetPort, HarnessPort, Logger, ProcessPort, StatePort, TrierarchSetup, WorkspacePort } from './ports.js';
2
2
  import type { Clock } from './shared/clock.js';
3
3
  /**
4
- * Use case: one pass of the trierarch's loop (docs/trierarch.md). It sees
5
- * what runs, lets the Reconciler decide, saves the state the actions start
6
- * from (an entry crewing is saved before the trierarch registers), then
7
- * carries the actions out, saving after each one that changes the list.
4
+ * Use case: one pass of the trierarch's loop (docs/trierarch.md, "Crewing a
5
+ * ship"). It reads the crew requests assigned to it and sees what runs, lets
6
+ * the Reconciler decide, saves the state the actions start from (an entry
7
+ * crewing is saved before the trierarch registers), then carries the actions
8
+ * out, saving after each one that changes the state. Each action is logged
9
+ * with its ship and outcome. A failed one is logged with what happens next,
10
+ * and the pass ends there: the next pass starts from the saved state and the
11
+ * requests as the fleet holds them then.
8
12
  */
9
13
  export type RunPass = () => Promise<void>;
10
14
  export interface RunPassDeps {
@@ -1,14 +1,28 @@
1
1
  import { putEntry, removeEntry, withState } from './entry.js';
2
2
  import { reconcile } from './reconciler.js';
3
+ const NEXT_AFTER_FAILURE = 'the next pass tries again; aeolus-trierarch status and list show where it stands';
3
4
  export function createRunPass(deps) {
4
5
  return async () => {
5
- const loaded = await deps.state.load();
6
- const observed = await observe(loaded, deps);
7
- const reconciled = reconcile(loaded, { observed, now: deps.clock.now(), configuration: deps.setup.configuration });
8
- let state = reconciled.state;
9
- await deps.state.save(state);
10
- for (const action of reconciled.actions) {
11
- state = await carryOut(state, { action, deps });
6
+ let state = await deps.state.load();
7
+ let action;
8
+ try {
9
+ const requests = await deps.fleet.assignedRequests();
10
+ const observed = await observe(state, deps);
11
+ const reconciled = reconcile(state, { requests, observed, now: deps.clock.now(), configuration: deps.setup.configuration });
12
+ state = reconciled.state;
13
+ await deps.state.save(state);
14
+ for (action of reconciled.actions) {
15
+ state = await carryOut(state, { action, deps });
16
+ }
17
+ }
18
+ catch (error) {
19
+ const reason = error instanceof Error ? error.message : String(error);
20
+ if (action === undefined || action.kind === 'argo' || action.kind === 'status' || action.kind === 'refuse') {
21
+ deps.logger.warn(`The pass failed${action === undefined ? '' : ` at ${action.kind}`}: ${reason}; ${NEXT_AFTER_FAILURE}`);
22
+ }
23
+ else {
24
+ log(deps, { ...about(state, { shipId: action.shipId, action: action.kind }), outcome: `failed: ${reason}`, next: NEXT_AFTER_FAILURE });
25
+ }
12
26
  }
13
27
  };
14
28
  }
@@ -36,16 +50,46 @@ async function observe(state, deps) {
36
50
  }
37
51
  return { sessions, worktrees, ships };
38
52
  }
53
+ function log(deps, logged) {
54
+ deps.logger.action({ time: deps.clock.now(), ...logged });
55
+ }
56
+ /** Which ship a log line is about, with its name once the state knows it. */
57
+ function about(state, of) {
58
+ const shipName = state.entries[of.shipId]?.shipName;
59
+ return { ...of, ...(shipName !== undefined && { shipName }) };
60
+ }
39
61
  async function carryOut(state, at) {
40
62
  const { action, deps } = at;
41
- if (action.kind === 'notify') {
42
- await deps.fleet.send(action.message);
43
- return state;
44
- }
45
- if (action.kind === 'stop') {
46
- await deps.processes.stop(action.shipId);
47
- return state;
63
+ switch (action.kind) {
64
+ case 'argo':
65
+ await deps.fleet.reportToArgo(action.report);
66
+ return state;
67
+ case 'status':
68
+ await deps.fleet.writeStatus(action.shipId, action.status);
69
+ return state;
70
+ case 'refuse':
71
+ return refuse(state, { action, deps });
72
+ case 'confirm':
73
+ await deps.fleet.confirmRelease(action.shipId);
74
+ log(deps, { shipId: action.shipId, action: 'confirm', outcome: 'its request removed; this trierarch did not crew it' });
75
+ return state;
76
+ case 'stop':
77
+ await deps.processes.stop(action.shipId);
78
+ log(deps, { ...about(state, { shipId: action.shipId, action: 'stop' }), outcome: 'its session stopped' });
79
+ return state;
80
+ case 'forget':
81
+ return forget(state, { entry: action.entry, deps });
82
+ case 'release':
83
+ return release(state, { shipId: action.shipId, deps });
84
+ case 'crew':
85
+ case 'launch':
86
+ case 'wake':
87
+ case 'report':
88
+ return carryOutForEntry(state, { action, deps });
48
89
  }
90
+ }
91
+ async function carryOutForEntry(state, at) {
92
+ const { action, deps } = at;
49
93
  const entry = state.entries[action.shipId];
50
94
  if (entry === undefined) {
51
95
  return state;
@@ -65,33 +109,33 @@ async function carryOut(state, at) {
65
109
  options: entry.options,
66
110
  isFirstStart: false,
67
111
  });
112
+ log(deps, { ...about(state, { shipId: entry.shipId, action: 'launch' }), outcome: `started again in ${entry.folder}` });
68
113
  }
69
114
  return state;
70
115
  case 'wake':
71
116
  if (entry.folder !== undefined) {
72
117
  await harnessOf(entry, deps)?.wake({ shipId: entry.shipId, folder: entry.folder });
118
+ log(deps, { ...about(state, { shipId: entry.shipId, action: 'wake' }), outcome: 'woken, deliveries wait' });
73
119
  }
74
120
  return state;
75
121
  case 'report': {
76
122
  const crewToken = entry.folder === undefined ? undefined : await harnessOf(entry, deps)?.crewTokenOf(entry.folder);
77
123
  if (crewToken !== undefined) {
78
124
  await deps.fleet.report({ crewToken, state: 'blocked', note: action.note });
125
+ log(deps, { ...about(state, { shipId: entry.shipId, action: 'report' }), outcome: `reported ${action.note}` });
79
126
  }
80
127
  return state;
81
128
  }
82
- case 'release':
83
- return release(state, { entry, deps });
84
- case 'drop':
85
- return drop(state, { entry, deps });
86
129
  }
87
130
  }
88
131
  /**
89
- * Crews the ship: gets its starting prompt (fleet:crew) and registers with the
90
- * secret, so the session never sees it; makes the workspace, writes the
91
- * folder's identity (with its squadron) and starts the harness. A resumed crew
92
- * whose ship is crewed lost its register reply: the trierarch releases the
93
- * ship and crews it again. A ship crewed by another session meanwhile, or gone,
94
- * is dropped.
132
+ * Crews the ship (crew:run): gets its starting prompt and registers with the
133
+ * secret, so the session never sees it; makes the workspace (or uses the one
134
+ * it has), writes the folder's identity (with its squadron) and starts the
135
+ * harness, writing status crewing, then running. A resumed crew whose ship is
136
+ * crewed holds the ship by its own lease, or lost its register reply: the
137
+ * trierarch releases the ship and crews it again. A ship another session
138
+ * crews before its crew is left; a ship gone is forgotten.
95
139
  */
96
140
  async function crew(state, at) {
97
141
  const { entry, isResumed, deps } = at;
@@ -100,12 +144,19 @@ async function crew(state, at) {
100
144
  return state;
101
145
  }
102
146
  const ship = await deps.fleet.ship(entry.shipId);
103
- if (ship.kind === 'notFound' || ship.kind === 'retired' || (ship.kind === 'crewed' && !isResumed)) {
104
- return drop(state, { entry, deps });
147
+ if (ship.kind === 'notFound' || ship.kind === 'retired') {
148
+ return forget(state, { entry, deps });
149
+ }
150
+ if (ship.kind === 'crewed' && !isResumed) {
151
+ const next = removeEntry(state, entry.shipId);
152
+ await deps.state.save(next);
153
+ log(deps, { shipId: entry.shipId, shipName: ship.name, action: 'leave', outcome: 'crewed by another session, so the trierarch leaves it' });
154
+ return next;
105
155
  }
106
156
  if (ship.kind === 'crewed') {
107
157
  await deps.fleet.release(entry.shipId);
108
158
  }
159
+ await deps.fleet.writeStatus(entry.shipId, 'crewing');
109
160
  const { secret } = await deps.fleet.getStartingPrompt(entry.shipId);
110
161
  const { crewToken } = await deps.fleet.register({ shipId: entry.shipId, secret });
111
162
  const { folder } = await deps.workspace.prepare({ shipId: entry.shipId, shipName: ship.name, workspace: entry.workspace });
@@ -126,46 +177,70 @@ async function crew(state, at) {
126
177
  const now = deps.clock.now();
127
178
  const next = putEntry(state, { ...withState(entry, { state: 'running', now }), shipName: ship.name, folder, hasStarted: true });
128
179
  await deps.state.save(next);
129
- await deps.fleet.send(notice(entry, { name: 'running', now }));
180
+ await deps.fleet.writeStatus(entry.shipId, 'running');
181
+ log(deps, { shipId: entry.shipId, shipName: ship.name, action: 'crew', outcome: `crewed, ${entry.harness} started in ${folder}` });
130
182
  return next;
131
183
  }
132
- /** Release asked by a message: the lease ends whatever the worktree holds, then the workspace, then the answer. */
184
+ /**
185
+ * Its request was removed (row 7): the session stops, the lease ends
186
+ * whatever the worktree holds, then the workspace; only then does the
187
+ * trierarch confirm, and the request goes.
188
+ */
133
189
  async function release(state, at) {
134
- const { entry, deps } = at;
135
- await deps.processes.stop(entry.shipId);
136
- await deps.fleet.release(entry.shipId);
137
- const finished = await finishWorkspace(state, { entry, deps, isForced: entry.release?.isForced ?? false });
138
- const next = removeEntry(finished.state, entry.shipId);
139
- await deps.state.save(next);
140
- if (entry.release !== undefined) {
141
- const { messageId, sender } = entry.release;
142
- await deps.fleet.send({
143
- to: sender,
144
- inReplyTo: messageId,
145
- name: 'released',
146
- payload: { shipId: entry.shipId, workspace: finished.workspace, ...(finished.path !== undefined && { path: finished.path }) },
147
- idempotencyKey: `trierarch:${messageId}:released`,
148
- });
190
+ const { shipId, deps } = at;
191
+ const entry = state.entries[shipId];
192
+ if (entry === undefined) {
193
+ return state;
194
+ }
195
+ await deps.processes.stop(shipId);
196
+ if ((await deps.fleet.ship(shipId)).kind === 'crewed') {
197
+ await deps.fleet.release(shipId);
149
198
  }
199
+ const finished = await finishWorkspace(state, { entry, deps });
200
+ const next = removeEntry(finished.state, shipId);
201
+ await deps.state.save(next);
202
+ await deps.fleet.confirmRelease(shipId);
203
+ log(deps, { ...about(state, { shipId, action: 'release' }), outcome: `released, ${describeWorkspace(entry, finished)}` });
150
204
  return next;
151
205
  }
152
- /** The lease ended elsewhere (released, re-crewed or retired): never crewed again, its requester told. */
153
- async function drop(state, at) {
206
+ /**
207
+ * Its request is no longer assigned here, as when its ship is retired (gap
208
+ * rule 2): the session stops and its identity goes, but nothing the trierarch
209
+ * cannot tell is clean goes: its worktree stays, reported as an orphan.
210
+ */
211
+ async function forget(state, at) {
154
212
  const { entry, deps } = at;
155
213
  await deps.processes.stop(entry.shipId);
156
- const finished = await finishWorkspace(state, { entry, deps, isForced: false });
157
- const next = removeEntry(finished.state, entry.shipId);
214
+ if (entry.folder !== undefined) {
215
+ await harnessOf(entry, deps)?.removeIdentity(entry.folder);
216
+ }
217
+ const next = removeEntry(state, entry.shipId);
218
+ await deps.state.save(next);
219
+ log(deps, { shipId: entry.shipId, ...(entry.shipName !== undefined && { shipName: entry.shipName }), action: 'forget', outcome: 'its request is no longer assigned here, so its session stopped' });
220
+ return next;
221
+ }
222
+ /** Tells argo, once per settings version, that this trierarch cannot crew them. */
223
+ async function refuse(state, at) {
224
+ const { action, deps } = at;
225
+ const ship = await deps.fleet.ship(action.shipId);
226
+ const name = ship.kind === 'awaitingCrew' || ship.kind === 'crewed' ? ship.name : action.shipId;
227
+ const { field, reason } = action.refusal;
228
+ await deps.fleet.reportToArgo({
229
+ text: `${name} (${action.shipId}): this trierarch cannot crew settings version ${String(action.settingsVersion)}: ${field === undefined ? reason : `${field}: ${reason}`}`,
230
+ idempotencyKey: `trierarch:refused:${action.shipId}:${String(action.settingsVersion)}`,
231
+ });
232
+ const next = { ...state, refused: { ...state.refused, [action.shipId]: action.settingsVersion } };
158
233
  await deps.state.save(next);
159
- await deps.fleet.send(notice(entry, { name: 'leaseEnded', now: deps.clock.now() }));
234
+ deps.logger.warn(`Cannot crew ${name} (${action.shipId}), settings version ${String(action.settingsVersion)}: ${reason}`);
160
235
  return next;
161
236
  }
162
237
  /**
163
238
  * The workspace of an entry that ends: a worktree the trierarch made is
164
- * removed when clean (or forced), and kept and reported when not; a
165
- * configured folder is never removed. The identity goes either way.
239
+ * removed when clean, and kept and reported when not; a configured folder is
240
+ * never removed. The identity goes either way.
166
241
  */
167
242
  async function finishWorkspace(state, at) {
168
- const { entry, deps, isForced } = at;
243
+ const { entry, deps } = at;
169
244
  const { folder } = entry;
170
245
  if (folder === undefined) {
171
246
  return { state, workspace: 'removed' };
@@ -174,15 +249,22 @@ async function finishWorkspace(state, at) {
174
249
  if (entry.workspace.kind === 'folder') {
175
250
  return { state, workspace: 'kept', path: folder };
176
251
  }
177
- if (isForced || (await deps.workspace.isClean(folder))) {
252
+ if (await deps.workspace.isClean(folder)) {
178
253
  await deps.workspace.remove(folder);
179
254
  return { state, workspace: 'removed' };
180
255
  }
181
256
  deps.logger.warn(`Kept the worktree of ${entry.shipId}, which has changes: ${folder}`);
182
257
  return { state: { ...state, kept: [...state.kept, { shipId: entry.shipId, path: folder }] }, workspace: 'kept', path: folder };
183
258
  }
259
+ /** What became of an ended entry's workspace, as its log line says it. */
260
+ function describeWorkspace(entry, finished) {
261
+ if (finished.workspace === 'removed') {
262
+ return 'its worktree removed';
263
+ }
264
+ return entry.workspace.kind === 'folder' ? `its folder kept: ${finished.path ?? ''}` : `its worktree kept with changes: ${finished.path ?? ''}`;
265
+ }
184
266
  /**
185
- * The adapter of the entry's harness. A want names only a harness the
267
+ * The adapter of the entry's harness. Settings name only a harness the
186
268
  * configuration offers, and the trierarch starts with an adapter for each, so
187
269
  * none missing is a setup gone wrong: logged, and the entry left as it is.
188
270
  */
@@ -193,7 +275,4 @@ function harnessOf(entry, deps) {
193
275
  }
194
276
  return harness;
195
277
  }
196
- function notice(entry, at) {
197
- return { to: entry.requester, name: at.name, payload: { shipId: entry.shipId }, idempotencyKey: `trierarch:${at.name}:${entry.shipId}:${at.now.toISOString()}` };
198
- }
199
278
  //# sourceMappingURL=run-pass.js.map