@sift-wiki/conductor 0.1.0 → 0.2.0-beta.2

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 (132) hide show
  1. package/README.md +28 -58
  2. package/dist/adapters/claudeAgent.js +1 -0
  3. package/dist/adapters/claudeAgent.js.map +1 -1
  4. package/dist/adapters/codexAgent.js +1 -0
  5. package/dist/adapters/codexAgent.js.map +1 -1
  6. package/dist/adapters/fakeAgent.js +1 -0
  7. package/dist/adapters/fakeAgent.js.map +1 -1
  8. package/dist/adapters/httpAgent.js +1 -0
  9. package/dist/adapters/httpAgent.js.map +1 -1
  10. package/dist/adapters/processAgent.js +4 -0
  11. package/dist/adapters/processAgent.js.map +1 -1
  12. package/dist/adapters/provider/runProvider.js +4 -0
  13. package/dist/adapters/provider/runProvider.js.map +1 -1
  14. package/dist/adapters/provider/store.js +3 -4
  15. package/dist/adapters/provider/store.js.map +1 -1
  16. package/dist/adapters/types.d.ts +9 -0
  17. package/dist/cli.d.ts +12 -0
  18. package/dist/cli.js +44 -3
  19. package/dist/cli.js.map +1 -1
  20. package/dist/conductorClient.d.ts +245 -17
  21. package/dist/conductorClient.js +147 -38
  22. package/dist/conductorClient.js.map +1 -1
  23. package/dist/config.js +4 -5
  24. package/dist/config.js.map +1 -1
  25. package/dist/daemon.d.ts +23 -6
  26. package/dist/daemon.js +173 -95
  27. package/dist/daemon.js.map +1 -1
  28. package/dist/desktop/app/contracts.d.ts +71 -0
  29. package/dist/desktop/app/contracts.js +19 -0
  30. package/dist/desktop/app/contracts.js.map +1 -0
  31. package/dist/desktop/app/controller.d.ts +58 -0
  32. package/dist/desktop/app/controller.js +161 -0
  33. package/dist/desktop/app/controller.js.map +1 -0
  34. package/dist/desktop/app/runtimeController.d.ts +29 -0
  35. package/dist/desktop/app/runtimeController.js +55 -0
  36. package/dist/desktop/app/runtimeController.js.map +1 -0
  37. package/dist/localApi/authorizedPairing.d.ts +12 -0
  38. package/dist/localApi/authorizedPairing.js +18 -0
  39. package/dist/localApi/authorizedPairing.js.map +1 -0
  40. package/dist/localApi/contracts.d.ts +264 -0
  41. package/dist/localApi/contracts.js +191 -0
  42. package/dist/localApi/contracts.js.map +1 -0
  43. package/dist/localApi/recovery.d.ts +66 -0
  44. package/dist/localApi/recovery.js +115 -0
  45. package/dist/localApi/recovery.js.map +1 -0
  46. package/dist/localApi/server.d.ts +20 -0
  47. package/dist/localApi/server.js +414 -0
  48. package/dist/localApi/server.js.map +1 -0
  49. package/dist/localApi/workConsole.d.ts +74 -0
  50. package/dist/localApi/workConsole.js +342 -0
  51. package/dist/localApi/workConsole.js.map +1 -0
  52. package/dist/localApi/workContracts.d.ts +213 -0
  53. package/dist/localApi/workContracts.js +130 -0
  54. package/dist/localApi/workContracts.js.map +1 -0
  55. package/dist/localApp/platform.d.ts +2 -0
  56. package/dist/localApp/platform.js +57 -0
  57. package/dist/localApp/platform.js.map +1 -0
  58. package/dist/localApp/service.d.ts +25 -0
  59. package/dist/localApp/service.js +126 -0
  60. package/dist/localApp/service.js.map +1 -0
  61. package/dist/protocol/fenced.d.ts +135 -0
  62. package/dist/protocol/fenced.js +142 -0
  63. package/dist/protocol/fenced.js.map +1 -0
  64. package/dist/redaction.js +2 -0
  65. package/dist/redaction.js.map +1 -1
  66. package/dist/runtime/atomicFile.d.ts +6 -0
  67. package/dist/runtime/atomicFile.js +78 -0
  68. package/dist/runtime/atomicFile.js.map +1 -0
  69. package/dist/runtime/daemonCapabilities.d.ts +7 -0
  70. package/dist/runtime/daemonCapabilities.js +24 -0
  71. package/dist/runtime/daemonCapabilities.js.map +1 -0
  72. package/dist/runtime/eventOutbox.d.ts +100 -0
  73. package/dist/runtime/eventOutbox.js +206 -0
  74. package/dist/runtime/eventOutbox.js.map +1 -0
  75. package/dist/runtime/executionJournal.d.ts +102 -0
  76. package/dist/runtime/executionJournal.js +209 -0
  77. package/dist/runtime/executionJournal.js.map +1 -0
  78. package/dist/runtime/executionSafety.d.ts +76 -0
  79. package/dist/runtime/executionSafety.js +207 -0
  80. package/dist/runtime/executionSafety.js.map +1 -0
  81. package/dist/runtime/fencedExecutionState.d.ts +43 -0
  82. package/dist/runtime/fencedExecutionState.js +158 -0
  83. package/dist/runtime/fencedExecutionState.js.map +1 -0
  84. package/dist/runtime/leaseManager.d.ts +38 -0
  85. package/dist/runtime/leaseManager.js +102 -0
  86. package/dist/runtime/leaseManager.js.map +1 -0
  87. package/dist/runtime/localLogSpool.d.ts +1 -0
  88. package/dist/runtime/localLogSpool.js +4 -0
  89. package/dist/runtime/localLogSpool.js.map +1 -1
  90. package/dist/runtime/localRunQueue.d.ts +1 -1
  91. package/dist/runtime/localRunQueue.js +8 -0
  92. package/dist/runtime/localRunQueue.js.map +1 -1
  93. package/dist/runtime/localSessionCache.d.ts +1 -1
  94. package/dist/runtime/localSessionCache.js.map +1 -1
  95. package/dist/runtime/process.d.ts +13 -1
  96. package/dist/runtime/process.js +39 -9
  97. package/dist/runtime/process.js.map +1 -1
  98. package/dist/runtime/recoveryCoordinator.d.ts +19 -0
  99. package/dist/runtime/recoveryCoordinator.js +183 -0
  100. package/dist/runtime/recoveryCoordinator.js.map +1 -0
  101. package/dist/runtime/runtimeLock.d.ts +33 -0
  102. package/dist/runtime/runtimeLock.js +140 -0
  103. package/dist/runtime/runtimeLock.js.map +1 -0
  104. package/dist/runtime/runtimeService.d.ts +6 -1
  105. package/dist/runtime/runtimeService.js +54 -20
  106. package/dist/runtime/runtimeService.js.map +1 -1
  107. package/dist/runtime/taskExecution.d.ts +2 -0
  108. package/dist/runtime/taskExecution.js +18 -12
  109. package/dist/runtime/taskExecution.js.map +1 -1
  110. package/dist/types.d.ts +28 -13
  111. package/dist/userAuth/service.d.ts +26 -0
  112. package/dist/userAuth/service.js +170 -0
  113. package/dist/userAuth/service.js.map +1 -0
  114. package/dist/userAuth/store.d.ts +42 -0
  115. package/dist/userAuth/store.js +160 -0
  116. package/dist/userAuth/store.js.map +1 -0
  117. package/dist/userAuth/types.d.ts +63 -0
  118. package/dist/userAuth/types.js +29 -0
  119. package/dist/userAuth/types.js.map +1 -0
  120. package/dist/version.d.ts +1 -1
  121. package/dist/version.js +1 -1
  122. package/dist/version.js.map +1 -1
  123. package/dist/workTypes.d.ts +162 -31
  124. package/dist/workTypes.js +31 -0
  125. package/dist/workTypes.js.map +1 -1
  126. package/dist-web/assets/index-CWAdDb9V.js +72 -0
  127. package/dist-web/assets/index-CWfnzdLn.css +1 -0
  128. package/dist-web/index.html +15 -0
  129. package/docs/provider-setup.md +81 -0
  130. package/docs/quickstart.md +62 -0
  131. package/docs/troubleshooting.md +63 -0
  132. package/package.json +13 -3
@@ -0,0 +1,183 @@
1
+ import { ConductorApiError } from "../conductorClient.js";
2
+ export async function reconcileUnfinishedAttempts(input) {
3
+ const unfinished = await input.journalStore.listUnfinished();
4
+ if (unfinished.length === 0) {
5
+ return { reconciledAttempts: 0, resumedAttempts: 0, closedAttempts: 0, canClaim: true };
6
+ }
7
+ if (input.client.reconcileAttempt === undefined) {
8
+ throw new Error("Sift reconciliation is unavailable while unfinished fenced attempts exist.");
9
+ }
10
+ let resumedAttempts = 0;
11
+ let closedAttempts = 0;
12
+ let canClaim = true;
13
+ for (const entry of unfinished) {
14
+ const journal = await updateJournal(input, entry.journal, { phase: "recovering" });
15
+ const adapter = input.adapters.find((candidate) => candidate.localKey === journal.localKey);
16
+ const providerResumeSupported = adapter?.resumeSupport === "session";
17
+ const decision = await input.client.reconcileAttempt(input.credential, {
18
+ attemptId: journal.authority.attemptId,
19
+ leaseGeneration: journal.authority.leaseGeneration,
20
+ lastAcknowledgedClientSequence: journal.lastAcknowledgedClientSequence,
21
+ providerResumeSupported,
22
+ supervisedProcessRunning: false,
23
+ ...(journal.terminalResult === undefined
24
+ ? {}
25
+ : {
26
+ terminalResult: {
27
+ disposition: journal.terminalResult.status === "overtime"
28
+ ? "failed"
29
+ : journal.terminalResult.status,
30
+ summary: { summary: journal.terminalResult.summary },
31
+ },
32
+ }),
33
+ });
34
+ if (decision.decision === "resume") {
35
+ resumedAttempts += 1;
36
+ if (!providerResumeSupported && journal.terminalResult === undefined) {
37
+ await updateJournal(input, journal, {
38
+ phase: "interrupted",
39
+ interruptionReason: "Sift returned resume for a provider without verified safe resume support.",
40
+ });
41
+ canClaim = false;
42
+ continue;
43
+ }
44
+ const resumed = await applyResume(input, journal, { ...decision, decision: "resume" });
45
+ if (resumed.terminalResult === undefined)
46
+ canClaim = false;
47
+ continue;
48
+ }
49
+ if (decision.decision === "stop" && !isTerminalCanonicalStatus(decision.canonicalStatus)) {
50
+ if (decision.cancellationRequested) {
51
+ try {
52
+ const settled = await settleCancellation(input, journal);
53
+ await updateJournal(input, journal, {
54
+ phase: "terminal",
55
+ terminalResult: journal.terminalResult ?? {
56
+ status: "cancelled",
57
+ summary: settled.summary,
58
+ },
59
+ interruptionReason: "Canonical cancellation confirmed during recovery.",
60
+ });
61
+ await input.outbox.discardAttempt(journal.attemptId);
62
+ closedAttempts += 1;
63
+ continue;
64
+ }
65
+ catch (error) {
66
+ canClaim = false;
67
+ await updateJournal(input, journal, {
68
+ phase: "recovering",
69
+ interruptionReason: `Cancellation settlement remains pending: ${errorMessage(error)}`,
70
+ });
71
+ continue;
72
+ }
73
+ }
74
+ canClaim = false;
75
+ await updateJournal(input, journal, {
76
+ phase: "recovering",
77
+ interruptionReason: decision.reason ?? "Sift returned stop while canonical work remains nonterminal.",
78
+ });
79
+ continue;
80
+ }
81
+ await updateJournal(input, journal, decisionJournalUpdate(decision));
82
+ await input.outbox.discardAttempt(journal.attemptId);
83
+ closedAttempts += 1;
84
+ }
85
+ return {
86
+ reconciledAttempts: unfinished.length,
87
+ resumedAttempts,
88
+ closedAttempts,
89
+ canClaim,
90
+ };
91
+ }
92
+ async function settleCancellation(input, journal) {
93
+ const summary = journal.terminalResult?.status === "cancelled"
94
+ ? journal.terminalResult.summary
95
+ : "Stopped local execution after Sift cancellation during recovery.";
96
+ const options = {
97
+ authority: journal.authority,
98
+ idempotencyKey: journal.settlementIdempotencyKey ?? `recovery-cancel:${journal.attemptId}`,
99
+ };
100
+ if (journal.taskRecordId !== undefined) {
101
+ if (input.workClient === undefined) {
102
+ throw new Error("Task cancellation settlement client is unavailable.");
103
+ }
104
+ await input.workClient.setTaskDisposition(input.credential, journal.runId, journal.taskRecordId, "cancelled", { summary }, options);
105
+ return { summary };
106
+ }
107
+ if (input.client.acknowledgeCancellation === undefined) {
108
+ throw new Error("Run cancellation settlement client is unavailable.");
109
+ }
110
+ await input.client.acknowledgeCancellation(input.credential, journal.runId, { summary }, options);
111
+ return { summary };
112
+ }
113
+ function isTerminalCanonicalStatus(status) {
114
+ return status === "completed" || status === "failed" || status === "cancelled";
115
+ }
116
+ function errorMessage(error) {
117
+ return error instanceof Error ? error.message : "Unknown cancellation settlement failure.";
118
+ }
119
+ async function applyResume(input, journal, decision) {
120
+ if (decision.authority === undefined) {
121
+ throw new Error("Resume reconciliation omitted refreshed authority.");
122
+ }
123
+ let next = await updateJournal(input, journal, {
124
+ authority: decision.authority,
125
+ lastAcknowledgedClientSequence: Math.max(journal.lastAcknowledgedClientSequence, decision.lastAcknowledgedClientSequence),
126
+ phase: "recovering",
127
+ });
128
+ await input.outbox.acknowledge(next.attemptId, next.lastAcknowledgedClientSequence);
129
+ for (const entry of await input.outbox.listAttempt(next.attemptId)) {
130
+ let response;
131
+ try {
132
+ response = await input.client.appendRunEvent(input.credential, next.runId, {
133
+ eventType: entry.event.eventType,
134
+ ...(entry.event.payload === undefined ? {} : { payload: entry.event.payload }),
135
+ ...(entry.event.occurredAt === undefined ? {} : { occurredAt: entry.event.occurredAt }),
136
+ clientEventId: entry.clientEventId,
137
+ clientSequence: entry.clientSequence,
138
+ authority: next.authority,
139
+ });
140
+ }
141
+ catch (error) {
142
+ if (error instanceof ConductorApiError && error.disposition === "retryable")
143
+ throw error;
144
+ throw error;
145
+ }
146
+ const acknowledged = acknowledgementSequence(response);
147
+ if (acknowledged === undefined) {
148
+ throw new Error("Fenced event delivery response omitted acknowledgedClientSequence.");
149
+ }
150
+ await input.outbox.acknowledge(next.attemptId, acknowledged);
151
+ next = await updateJournal(input, next, {
152
+ lastAcknowledgedClientSequence: Math.max(next.lastAcknowledgedClientSequence, acknowledged),
153
+ });
154
+ }
155
+ return next;
156
+ }
157
+ function decisionJournalUpdate(decision) {
158
+ switch (decision.decision) {
159
+ case "already_terminal":
160
+ return { phase: "terminal", interruptionReason: decision.reason ?? "Canonical run is already terminal." };
161
+ case "superseded":
162
+ return { phase: "superseded", interruptionReason: decision.reason ?? "Another attempt owns this work." };
163
+ case "stop":
164
+ return { phase: "interrupted", interruptionReason: decision.reason ?? "Sift instructed local execution to stop." };
165
+ case "retry_as_new_attempt":
166
+ return { phase: "interrupted", interruptionReason: decision.reason ?? "Retry requires a new fenced attempt." };
167
+ case "resume":
168
+ throw new Error("Resume decisions require refreshed authority handling.");
169
+ }
170
+ }
171
+ async function updateJournal(input, journal, update) {
172
+ const next = {
173
+ ...journal,
174
+ ...update,
175
+ updatedAt: (input.now ?? (() => new Date()))().toISOString(),
176
+ };
177
+ await input.journalStore.write(next);
178
+ return next;
179
+ }
180
+ function acknowledgementSequence(response) {
181
+ return response.acknowledgedClientSequence;
182
+ }
183
+ //# sourceMappingURL=recoveryCoordinator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recoveryCoordinator.js","sourceRoot":"","sources":["../../src/runtime/recoveryCoordinator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { z } from "zod";
2
+ declare const lockSchema: z.ZodObject<{
3
+ schemaVersion: z.ZodLiteral<1>;
4
+ identityKey: z.ZodString;
5
+ pid: z.ZodNumber;
6
+ processStartMarker: z.ZodString;
7
+ nonce: z.ZodString;
8
+ acquiredAt: z.ZodISODateTime;
9
+ }, z.core.$strict>;
10
+ export type RuntimeLockRecord = z.infer<typeof lockSchema>;
11
+ export type RuntimeLockHandle = {
12
+ record: RuntimeLockRecord;
13
+ release(): Promise<void>;
14
+ };
15
+ export type RuntimeLockOptions = {
16
+ pid?: number | undefined;
17
+ now?: (() => Date) | undefined;
18
+ createNonce?: (() => string) | undefined;
19
+ readProcessStartMarker?: ((pid: number) => Promise<string | undefined>) | undefined;
20
+ };
21
+ export declare class RuntimeIdentityLock {
22
+ readonly path: string;
23
+ private readonly options;
24
+ constructor(path?: string, options?: RuntimeLockOptions);
25
+ acquire(identityKey: string): Promise<RuntimeLockHandle>;
26
+ private tryCreate;
27
+ private readExisting;
28
+ private recoverStaleLock;
29
+ private handle;
30
+ }
31
+ export declare function defaultRuntimeLockPath(env?: NodeJS.ProcessEnv): string;
32
+ export declare function readProcessStartMarker(pid: number): Promise<string | undefined>;
33
+ export {};
@@ -0,0 +1,140 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { execFile } from "node:child_process";
3
+ import { chmod, mkdir, open, readFile, rename, rm } from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { promisify } from "node:util";
6
+ import { z } from "zod";
7
+ import { defaultConfigPath } from "../config.js";
8
+ import { isNodeError } from "./atomicFile.js";
9
+ const execFileAsync = promisify(execFile);
10
+ const lockSchema = z.object({
11
+ schemaVersion: z.literal(1),
12
+ identityKey: z.string().min(1).max(500),
13
+ pid: z.number().int().positive(),
14
+ processStartMarker: z.string().min(1).max(500),
15
+ nonce: z.string().min(1),
16
+ acquiredAt: z.iso.datetime(),
17
+ }).strict();
18
+ export class RuntimeIdentityLock {
19
+ path;
20
+ options;
21
+ constructor(path = defaultRuntimeLockPath(), options = {}) {
22
+ this.path = path;
23
+ this.options = options;
24
+ }
25
+ async acquire(identityKey) {
26
+ await mkdir(path.dirname(this.path), { recursive: true, mode: 0o700 });
27
+ await chmod(path.dirname(this.path), 0o700);
28
+ const pid = this.options.pid ?? process.pid;
29
+ const markerReader = this.options.readProcessStartMarker ?? readProcessStartMarker;
30
+ const processStartMarker = await markerReader(pid);
31
+ if (processStartMarker === undefined) {
32
+ throw new Error("Cannot establish a PID-reuse-safe runtime identity.");
33
+ }
34
+ const record = lockSchema.parse({
35
+ schemaVersion: 1,
36
+ identityKey,
37
+ pid,
38
+ processStartMarker,
39
+ nonce: (this.options.createNonce ?? randomUUID)(),
40
+ acquiredAt: (this.options.now ?? (() => new Date()))().toISOString(),
41
+ });
42
+ for (let attempt = 0; attempt < 3; attempt += 1) {
43
+ if (await this.tryCreate(record))
44
+ return this.handle(record);
45
+ const existing = await this.readExisting();
46
+ if (existing !== undefined && await sameLiveProcess(existing, markerReader)) {
47
+ throw new Error("Another Conductor runtime already owns this paired identity and state directory.");
48
+ }
49
+ await this.recoverStaleLock(existing);
50
+ }
51
+ throw new Error("Could not acquire the Conductor runtime identity lock.");
52
+ }
53
+ async tryCreate(record) {
54
+ try {
55
+ const handle = await open(this.path, "wx", 0o600);
56
+ try {
57
+ await handle.writeFile(`${JSON.stringify(record, null, 2)}\n`, "utf8");
58
+ await handle.sync();
59
+ }
60
+ finally {
61
+ await handle.close();
62
+ }
63
+ return true;
64
+ }
65
+ catch (error) {
66
+ if (isNodeError(error) && error.code === "EEXIST")
67
+ return false;
68
+ throw error;
69
+ }
70
+ }
71
+ async readExisting() {
72
+ try {
73
+ return lockSchema.parse(JSON.parse(await readFile(this.path, "utf8")));
74
+ }
75
+ catch (error) {
76
+ if (isNodeError(error) && error.code === "ENOENT")
77
+ return undefined;
78
+ if (error instanceof SyntaxError || error instanceof z.ZodError)
79
+ return undefined;
80
+ throw error;
81
+ }
82
+ }
83
+ async recoverStaleLock(existing) {
84
+ try {
85
+ await rename(this.path, `${this.path}.stale-${existing?.nonce ?? randomUUID()}`);
86
+ }
87
+ catch (error) {
88
+ if (!isNodeError(error) || error.code !== "ENOENT")
89
+ throw error;
90
+ }
91
+ }
92
+ handle(record) {
93
+ return {
94
+ record,
95
+ release: async () => {
96
+ const existing = await this.readExisting();
97
+ if (existing?.nonce === record.nonce)
98
+ await rm(this.path, { force: true });
99
+ },
100
+ };
101
+ }
102
+ }
103
+ export function defaultRuntimeLockPath(env = process.env) {
104
+ return path.join(path.dirname(defaultConfigPath(env)), "runtime", "conductor.lock");
105
+ }
106
+ async function sameLiveProcess(record, markerReader) {
107
+ try {
108
+ process.kill(record.pid, 0);
109
+ }
110
+ catch (error) {
111
+ if (isNodeError(error) && error.code === "EPERM")
112
+ return true;
113
+ return false;
114
+ }
115
+ return await markerReader(record.pid) === record.processStartMarker;
116
+ }
117
+ export async function readProcessStartMarker(pid) {
118
+ if (process.platform === "linux") {
119
+ try {
120
+ const stat = await readFile(`/proc/${String(pid)}/stat`, "utf8");
121
+ return stat.trim().split(/\s+/u)[21];
122
+ }
123
+ catch {
124
+ return undefined;
125
+ }
126
+ }
127
+ const command = process.platform === "win32" ? "powershell.exe" : "ps";
128
+ const args = process.platform === "win32"
129
+ ? ["-NoProfile", "-Command", `(Get-Process -Id ${String(pid)}).StartTime.ToUniversalTime().Ticks`]
130
+ : ["-o", "lstart=", "-p", String(pid)];
131
+ try {
132
+ const { stdout } = await execFileAsync(command, args, { timeout: 2_000 });
133
+ const marker = stdout.trim();
134
+ return marker.length === 0 ? undefined : marker;
135
+ }
136
+ catch {
137
+ return undefined;
138
+ }
139
+ }
140
+ //# sourceMappingURL=runtimeLock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtimeLock.js","sourceRoot":"","sources":["../../src/runtime/runtimeLock.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { DaemonOnceResult, RunDaemonOnceInput } from "../daemon.js";
2
+ import type { RuntimeIdentityLock } from "./runtimeLock.js";
2
3
  export type RuntimeServiceState = "stopped" | "starting" | "running" | "stopping" | "failed";
3
4
  export type RuntimeServiceStatus = {
4
5
  state: RuntimeServiceState;
@@ -9,6 +10,7 @@ export type RuntimeServiceStatus = {
9
10
  };
10
11
  export declare class HeadlessRuntimeService {
11
12
  private readonly input;
13
+ private readonly runtimeLock?;
12
14
  private state;
13
15
  private startedAt;
14
16
  private stoppedAt;
@@ -16,7 +18,8 @@ export declare class HeadlessRuntimeService {
16
18
  private lastErrorMessage;
17
19
  private controller;
18
20
  private runPromise;
19
- constructor(input: Omit<RunDaemonOnceInput, "signal">);
21
+ private lockHandle;
22
+ constructor(input: Omit<RunDaemonOnceInput, "signal">, runtimeLock?: RuntimeIdentityLock | undefined);
20
23
  status(): RuntimeServiceStatus;
21
24
  runOnce(): Promise<DaemonOnceResult>;
22
25
  start(): Promise<RuntimeServiceStatus>;
@@ -24,4 +27,6 @@ export declare class HeadlessRuntimeService {
24
27
  restart(): Promise<RuntimeServiceStatus>;
25
28
  waitUntilStopped(): Promise<RuntimeServiceStatus>;
26
29
  private runUntilStopped;
30
+ private acquireOwnership;
31
+ private releaseOwnership;
27
32
  }
@@ -1,7 +1,9 @@
1
+ import { createHash } from "node:crypto";
1
2
  import { runDaemon, runDaemonOnce } from "../daemon.js";
2
3
  import { redactSecrets } from "../redaction.js";
3
4
  export class HeadlessRuntimeService {
4
5
  input;
6
+ runtimeLock;
5
7
  state = "stopped";
6
8
  startedAt;
7
9
  stoppedAt;
@@ -9,8 +11,10 @@ export class HeadlessRuntimeService {
9
11
  lastErrorMessage;
10
12
  controller;
11
13
  runPromise;
12
- constructor(input) {
14
+ lockHandle;
15
+ constructor(input, runtimeLock) {
13
16
  this.input = input;
17
+ this.runtimeLock = runtimeLock;
14
18
  }
15
19
  status() {
16
20
  return {
@@ -30,6 +34,7 @@ export class HeadlessRuntimeService {
30
34
  this.stoppedAt = undefined;
31
35
  this.lastErrorMessage = undefined;
32
36
  try {
37
+ await this.acquireOwnership();
33
38
  this.state = "running";
34
39
  const result = await runDaemonOnce(this.input);
35
40
  this.lastResult = result;
@@ -43,6 +48,9 @@ export class HeadlessRuntimeService {
43
48
  this.lastErrorMessage = safeRuntimeErrorMessage(error);
44
49
  throw error;
45
50
  }
51
+ finally {
52
+ await this.releaseOwnership();
53
+ }
46
54
  }
47
55
  async start() {
48
56
  await Promise.resolve();
@@ -58,6 +66,15 @@ export class HeadlessRuntimeService {
58
66
  this.startedAt = new Date().toISOString();
59
67
  this.stoppedAt = undefined;
60
68
  this.lastErrorMessage = undefined;
69
+ try {
70
+ await this.acquireOwnership();
71
+ }
72
+ catch (error) {
73
+ this.state = "failed";
74
+ this.stoppedAt = new Date().toISOString();
75
+ this.lastErrorMessage = safeRuntimeErrorMessage(error);
76
+ throw error;
77
+ }
61
78
  this.runPromise = this.runUntilStopped(controller);
62
79
  this.state = "running";
63
80
  return this.status();
@@ -80,27 +97,44 @@ export class HeadlessRuntimeService {
80
97
  await this.runPromise;
81
98
  return this.status();
82
99
  }
83
- runUntilStopped(controller) {
84
- return runDaemon({ ...this.input, signal: controller.signal })
85
- .then(() => {
86
- if (this.controller !== controller) {
87
- return;
100
+ async runUntilStopped(controller) {
101
+ try {
102
+ await runDaemon({ ...this.input, signal: controller.signal });
103
+ if (this.controller === controller) {
104
+ this.state = "stopped";
105
+ this.stoppedAt = new Date().toISOString();
88
106
  }
89
- this.state = "stopped";
90
- this.stoppedAt = new Date().toISOString();
91
- this.controller = undefined;
92
- this.runPromise = undefined;
93
- })
94
- .catch((error) => {
95
- if (this.controller !== controller) {
96
- return;
107
+ }
108
+ catch (error) {
109
+ if (this.controller === controller) {
110
+ this.state = "failed";
111
+ this.stoppedAt = new Date().toISOString();
112
+ this.lastErrorMessage = safeRuntimeErrorMessage(error);
97
113
  }
98
- this.state = "failed";
99
- this.stoppedAt = new Date().toISOString();
100
- this.lastErrorMessage = safeRuntimeErrorMessage(error);
101
- this.controller = undefined;
102
- this.runPromise = undefined;
103
- });
114
+ }
115
+ finally {
116
+ if (this.controller === controller) {
117
+ this.controller = undefined;
118
+ this.runPromise = undefined;
119
+ }
120
+ await this.releaseOwnership();
121
+ }
122
+ }
123
+ async acquireOwnership() {
124
+ if (this.runtimeLock === undefined)
125
+ return;
126
+ const config = await this.input.store.read();
127
+ if (config === undefined)
128
+ throw new Error("No paired Conductor config found. Run pair first.");
129
+ const identityKey = config.conductorId ?? createHash("sha256")
130
+ .update(`${config.apiBaseUrl}\0${config.displayName}`)
131
+ .digest("hex");
132
+ this.lockHandle = await this.runtimeLock.acquire(identityKey);
133
+ }
134
+ async releaseOwnership() {
135
+ const handle = this.lockHandle;
136
+ this.lockHandle = undefined;
137
+ await handle?.release();
104
138
  }
105
139
  }
106
140
  function safeRuntimeErrorMessage(error) {
@@ -1 +1 @@
1
- {"version":3,"file":"runtimeService.js","sourceRoot":"","sources":["../../src/runtime/runtimeService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtimeService.js","sourceRoot":"","sources":["../../src/runtime/runtimeService.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { ConductorClient, ConductorWorkClient, ClaimedJob } from "../types.js";
2
+ import type { AttemptAuthority } from "../protocol/fenced.js";
2
3
  export type TaskExecutionClient = Pick<ConductorWorkClient, "readWorkContext" | "checkoutTask" | "createChildTasks" | "addTaskComment" | "registerArtifact" | "requestApproval" | "reportUsage" | "setTaskDisposition">;
3
4
  export type OpenTaskExecution = {
4
5
  taskId: string;
@@ -11,6 +12,7 @@ export declare function openTaskExecution(input: {
11
12
  workClient: TaskExecutionClient;
12
13
  credential: string;
13
14
  job: ClaimedJob;
15
+ authority?: AttemptAuthority | undefined;
14
16
  onHardStop?: (() => void) | undefined;
15
17
  }): Promise<OpenTaskExecution>;
16
18
  export declare function taskIdFromJob(job: ClaimedJob): string;
@@ -3,7 +3,7 @@ import { startLocalBridgeServer } from "../bridge/server.js";
3
3
  import { LocalBridgeSessionRegistry } from "../bridge/sessionRegistry.js";
4
4
  export async function openTaskExecution(input) {
5
5
  const taskId = taskIdFromJob(input.job);
6
- await input.workClient.checkoutTask(input.credential, input.job.runId, taskId);
6
+ await input.workClient.checkoutTask(input.credential, input.job.runId, taskId, mutationOptions(input.authority));
7
7
  const sessions = new LocalBridgeSessionRegistry();
8
8
  const session = sessions.create({
9
9
  runId: input.job.runId,
@@ -13,7 +13,7 @@ export async function openTaskExecution(input) {
13
13
  });
14
14
  const handler = createLocalBridgeHandler({
15
15
  sessions,
16
- client: bridgeClient(input.coreClient, input.workClient),
16
+ client: bridgeClient(input.coreClient, input.workClient, input.authority),
17
17
  machineCredential: input.credential,
18
18
  onHardStop: input.onHardStop,
19
19
  });
@@ -41,19 +41,25 @@ export function taskIdFromJob(job) {
41
41
  }
42
42
  return taskId;
43
43
  }
44
- function bridgeClient(core, work) {
44
+ function bridgeClient(core, work, authority) {
45
45
  return {
46
- readWorkContext: (...args) => work.readWorkContext(...args),
47
- checkoutTask: (...args) => work.checkoutTask(...args),
48
- createChildTasks: (...args) => work.createChildTasks(...args),
49
- addTaskComment: (...args) => work.addTaskComment(...args),
50
- registerArtifact: (...args) => work.registerArtifact(...args),
51
- requestApproval: (...args) => work.requestApproval(...args),
52
- reportUsage: (...args) => work.reportUsage(...args),
53
- setTaskDisposition: (...args) => work.setTaskDisposition(...args),
54
- appendRunEvent: (...args) => core.appendRunEvent(...args),
46
+ readWorkContext: (credential, runId, taskId) => work.readWorkContext(credential, runId, taskId, mutationOptions(authority)),
47
+ checkoutTask: (credential, runId, taskId) => work.checkoutTask(credential, runId, taskId, mutationOptions(authority)),
48
+ createChildTasks: (credential, runId, taskId, children) => work.createChildTasks(credential, runId, taskId, children, mutationOptions(authority)),
49
+ addTaskComment: (credential, runId, taskId, bodyMarkdown) => work.addTaskComment(credential, runId, taskId, bodyMarkdown, mutationOptions(authority)),
50
+ registerArtifact: (credential, runId, taskId, artifact) => work.registerArtifact(credential, runId, taskId, artifact, mutationOptions(authority)),
51
+ requestApproval: (credential, runId, taskId, request) => work.requestApproval(credential, runId, taskId, request, mutationOptions(authority)),
52
+ reportUsage: (credential, runId, taskId, usage) => work.reportUsage(credential, runId, taskId, usage, mutationOptions(authority)),
53
+ setTaskDisposition: (credential, runId, taskId, disposition, resultSummary) => work.setTaskDisposition(credential, runId, taskId, disposition, resultSummary, mutationOptions(authority)),
54
+ appendRunEvent: (credential, runId, event) => core.appendRunEvent(credential, runId, {
55
+ ...event,
56
+ ...(authority === undefined ? {} : { authority }),
57
+ }),
55
58
  };
56
59
  }
60
+ function mutationOptions(authority) {
61
+ return authority === undefined ? undefined : { authority };
62
+ }
57
63
  function bridgeSessionTtlMs(job) {
58
64
  const maxRunMinutes = job.wakeEnvelope?.limits.maxRunMinutes;
59
65
  return (maxRunMinutes ?? 60) * 60_000 + 60_000;
@@ -1 +1 @@
1
- {"version":3,"file":"taskExecution.js","sourceRoot":"","sources":["../../src/runtime/taskExecution.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"taskExecution.js","sourceRoot":"","sources":["../../src/runtime/taskExecution.ts"],"names":[],"mappings":"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"}