@timurproko/a1 0.1.1-dev.5 → 0.1.1-dev.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/README.md +32 -9
  2. package/bin/a1-guardian.js +22 -0
  3. package/bin/a1-ui.js +7 -4
  4. package/dist/native/darwin-arm64/a1-process-guardian +0 -0
  5. package/dist/native/darwin-arm64/manifest.json +20 -0
  6. package/dist/native/linux-x64/a1-process-guardian +0 -0
  7. package/dist/native/linux-x64/manifest.json +20 -0
  8. package/dist/native/win32-x64/a1-process-guardian.exe +0 -0
  9. package/dist/native/win32-x64/manifest.json +20 -0
  10. package/dist/src/composition/index.d.ts +26 -0
  11. package/dist/src/composition/index.js +88 -2
  12. package/dist/src/features/launch/runtime-selection.d.ts +2 -1
  13. package/dist/src/features/launch/runtime-selection.js +2 -2
  14. package/dist/src/features/owned-ui/index.d.ts +1 -0
  15. package/dist/src/features/owned-ui/index.js +1 -0
  16. package/dist/src/features/owned-ui/run.d.ts +6 -0
  17. package/dist/src/features/owned-ui/run.js +3 -1
  18. package/dist/src/features/owned-ui/settings-app.d.ts +22 -0
  19. package/dist/src/features/owned-ui/settings-app.js +631 -0
  20. package/dist/src/foundation/agent-engine-contracts/domain.d.ts +26 -0
  21. package/dist/src/foundation/launch-guardian/index.d.ts +1 -0
  22. package/dist/src/foundation/launch-guardian/index.js +1 -0
  23. package/dist/src/foundation/launch-guardian/main.d.ts +31 -0
  24. package/dist/src/foundation/launch-guardian/main.js +165 -0
  25. package/dist/src/foundation/lifecycle/commands.d.ts +40 -0
  26. package/dist/src/foundation/lifecycle/commands.js +1 -0
  27. package/dist/src/foundation/lifecycle/index.d.ts +2 -0
  28. package/dist/src/foundation/lifecycle/index.js +2 -0
  29. package/dist/src/foundation/lifecycle/launch-instance.d.ts +46 -0
  30. package/dist/src/foundation/lifecycle/launch-instance.js +134 -0
  31. package/dist/src/foundation/lifecycle/model.d.ts +6 -42
  32. package/dist/src/foundation/owned-ui-settings/declarations.d.ts +13 -0
  33. package/dist/src/foundation/owned-ui-settings/declarations.js +39 -0
  34. package/dist/src/foundation/owned-ui-settings/index.d.ts +6 -0
  35. package/dist/src/foundation/owned-ui-settings/index.js +6 -0
  36. package/dist/src/foundation/owned-ui-settings/migrations.d.ts +13 -0
  37. package/dist/src/foundation/owned-ui-settings/migrations.js +28 -0
  38. package/dist/src/foundation/owned-ui-settings/resolution.d.ts +45 -0
  39. package/dist/src/foundation/owned-ui-settings/resolution.js +147 -0
  40. package/dist/src/foundation/owned-ui-settings/sections.d.ts +70 -0
  41. package/dist/src/foundation/owned-ui-settings/sections.js +93 -0
  42. package/dist/src/foundation/owned-ui-settings/session.d.ts +44 -0
  43. package/dist/src/foundation/owned-ui-settings/session.js +145 -0
  44. package/dist/src/foundation/owned-ui-settings/store.d.ts +28 -0
  45. package/dist/src/foundation/owned-ui-settings/store.js +90 -0
  46. package/dist/src/foundation/pi-component-adapter/index.d.ts +1 -0
  47. package/dist/src/foundation/pi-component-adapter/index.js +1 -0
  48. package/dist/src/foundation/pi-component-adapter/shell-selectors-dialogs.d.ts +9 -1
  49. package/dist/src/foundation/pi-component-adapter/shell-selectors-dialogs.js +10 -8
  50. package/dist/src/foundation/pi-engine-adapter/adapter.d.ts +12 -3
  51. package/dist/src/foundation/pi-engine-adapter/adapter.js +73 -7
  52. package/dist/src/foundation/pi-engine-adapter/pi-settings-metadata.json +374 -0
  53. package/dist/src/foundation/pi-engine-adapter/public-main-entry.js +10 -1
  54. package/dist/src/foundation/pi-engine-adapter/settings-integration.d.ts +42 -2
  55. package/dist/src/foundation/pi-engine-adapter/settings-integration.js +185 -24
  56. package/dist/src/foundation/pi-engine-adapter/workflows.d.ts +9 -0
  57. package/dist/src/foundation/pi-owned-ui-integration/index.d.ts +1 -0
  58. package/dist/src/foundation/pi-owned-ui-integration/index.js +1 -0
  59. package/dist/src/foundation/pi-owned-ui-integration/route-host.d.ts +29 -0
  60. package/dist/src/foundation/pi-owned-ui-integration/route-host.js +1 -0
  61. package/dist/src/foundation/pi-owned-ui-integration/session-shell.d.ts +6 -0
  62. package/dist/src/foundation/pi-owned-ui-integration/session-shell.js +71 -1
  63. package/dist/src/foundation/pi-tui-runtime-adapter/adapter.d.ts +6 -0
  64. package/dist/src/foundation/pi-tui-runtime-adapter/adapter.js +9 -0
  65. package/dist/src/foundation/process-containment/artifact.d.ts +1 -0
  66. package/dist/src/foundation/process-containment/artifact.js +34 -0
  67. package/dist/src/foundation/process-containment/contracts.d.ts +31 -0
  68. package/dist/src/foundation/process-containment/contracts.js +35 -0
  69. package/dist/src/foundation/process-containment/index.d.ts +5 -0
  70. package/dist/src/foundation/process-containment/index.js +5 -0
  71. package/dist/src/foundation/process-containment/linux-process-inspector.d.ts +6 -0
  72. package/dist/src/foundation/process-containment/linux-process-inspector.js +26 -0
  73. package/dist/src/foundation/process-containment/native-guardian-containment.d.ts +16 -0
  74. package/dist/src/foundation/process-containment/native-guardian-containment.js +139 -0
  75. package/dist/src/foundation/process-containment/windows-process-inspector.d.ts +17 -0
  76. package/dist/src/foundation/process-containment/windows-process-inspector.js +53 -0
  77. package/dist/src/foundation/protocol/client.d.ts +2 -1
  78. package/dist/src/foundation/protocol/client.js +3 -0
  79. package/dist/src/foundation/protocol/messages.d.ts +5 -5
  80. package/dist/src/foundation/protocol/messages.js +1 -1
  81. package/dist/src/foundation/release/bootstrap.js +29 -10
  82. package/dist/src/foundation/release/cohort-selection.js +3 -3
  83. package/dist/src/foundation/release/cohort-state.d.ts +3 -2
  84. package/dist/src/foundation/release/process-cleanup.d.ts +1 -1
  85. package/dist/src/foundation/release/process-cleanup.js +2 -2
  86. package/dist/src/foundation/release/update.js +2 -2
  87. package/dist/src/foundation/storage/control-store.d.ts +8 -7
  88. package/dist/src/foundation/storage/control-store.js +105 -55
  89. package/dist/src/foundation/supervision/server.d.ts +4 -2
  90. package/dist/src/foundation/supervision/server.js +254 -87
  91. package/dist/src/foundation/transparent-terminal/command-resolution.js +6 -3
  92. package/dist/src/foundation/transparent-terminal/foreground-broker.d.ts +5 -13
  93. package/dist/src/foundation/transparent-terminal/foreground-broker.js +11 -68
  94. package/dist/src/foundation/transparent-terminal/main.js +1 -8
  95. package/dist/src/foundation/ui-apps/contracts.d.ts +42 -0
  96. package/dist/src/foundation/ui-apps/contracts.js +12 -0
  97. package/dist/src/foundation/ui-apps/host.d.ts +42 -0
  98. package/dist/src/foundation/ui-apps/host.js +152 -0
  99. package/dist/src/foundation/ui-apps/index.d.ts +3 -0
  100. package/dist/src/foundation/ui-apps/index.js +3 -0
  101. package/dist/src/foundation/ui-apps/registry.d.ts +11 -0
  102. package/dist/src/foundation/ui-apps/registry.js +32 -0
  103. package/dist/src/foundation/ui-components/dialog-panel.d.ts +36 -0
  104. package/dist/src/foundation/ui-components/dialog-panel.js +47 -0
  105. package/dist/src/foundation/ui-components/frame.d.ts +21 -0
  106. package/dist/src/foundation/ui-components/frame.js +54 -0
  107. package/dist/src/foundation/ui-components/index.d.ts +18 -0
  108. package/dist/src/foundation/ui-components/index.js +18 -0
  109. package/dist/src/foundation/ui-components/label.d.ts +8 -0
  110. package/dist/src/foundation/ui-components/label.js +36 -0
  111. package/dist/src/foundation/ui-components/line-input.d.ts +74 -0
  112. package/dist/src/foundation/ui-components/line-input.js +245 -0
  113. package/dist/src/foundation/ui-components/list-block.d.ts +66 -0
  114. package/dist/src/foundation/ui-components/list-block.js +176 -0
  115. package/dist/src/foundation/ui-components/list-view.d.ts +66 -0
  116. package/dist/src/foundation/ui-components/list-view.js +76 -0
  117. package/dist/src/foundation/ui-components/mouse.d.ts +15 -0
  118. package/dist/src/foundation/ui-components/mouse.js +46 -0
  119. package/dist/src/foundation/ui-components/pane.d.ts +33 -0
  120. package/dist/src/foundation/ui-components/pane.js +7 -0
  121. package/dist/src/foundation/ui-components/revision.d.ts +35 -0
  122. package/dist/src/foundation/ui-components/revision.js +79 -0
  123. package/dist/src/foundation/ui-components/scrollbar.d.ts +62 -0
  124. package/dist/src/foundation/ui-components/scrollbar.js +102 -0
  125. package/dist/src/foundation/ui-components/shortcuts.d.ts +57 -0
  126. package/dist/src/foundation/ui-components/shortcuts.js +81 -0
  127. package/dist/src/foundation/ui-components/spans.d.ts +7 -0
  128. package/dist/src/foundation/ui-components/spans.js +59 -0
  129. package/dist/src/foundation/ui-components/status-line.d.ts +16 -0
  130. package/dist/src/foundation/ui-components/status-line.js +14 -0
  131. package/dist/src/foundation/ui-components/stepper.d.ts +24 -0
  132. package/dist/src/foundation/ui-components/stepper.js +33 -0
  133. package/dist/src/foundation/ui-components/surface.d.ts +20 -0
  134. package/dist/src/foundation/ui-components/surface.js +38 -0
  135. package/dist/src/foundation/ui-components/text.d.ts +24 -0
  136. package/dist/src/foundation/ui-components/text.js +123 -0
  137. package/dist/src/foundation/ui-components/theme.d.ts +17 -0
  138. package/dist/src/foundation/ui-components/theme.js +12 -0
  139. package/dist/src/foundation/ui-components/value-menu.d.ts +41 -0
  140. package/dist/src/foundation/ui-components/value-menu.js +33 -0
  141. package/dist/src/product-identity.d.ts +2 -2
  142. package/dist/src/product-identity.js +2 -1
  143. package/dist/src/product-identity.json +3 -0
  144. package/docs/architecture/boundaries.md +31 -13
  145. package/docs/architecture/process-guardian-provenance.md +26 -0
  146. package/docs/architecture/toolchain.md +6 -0
  147. package/docs/architecture/ui-reference-provenance.md +50 -0
  148. package/docs/ci-release-runbook.md +38 -42
  149. package/docs/features/launch-profiles.md +7 -1
  150. package/docs/manual-launch-instance-acceptance.md +66 -0
  151. package/package.json +11 -12
@@ -3,6 +3,7 @@ import { mkdirSync } from "node:fs";
3
3
  import { dirname } from "node:path";
4
4
  import { PRODUCT_IDENTITY } from "../../product-identity.js";
5
5
  import { assertManagedAgentDescriptor, assertRecoveryAuthority, assertTerminalSessionLaunch, assertTerminalTopologySnapshot, } from "../workspace-contracts/index.js";
6
+ import { assertLaunchInstance, assertLaunchInstanceOutcome, assertNativeProcessIdentity, assertProcessContainmentIdentity, } from "../lifecycle/index.js";
6
7
  export const DEFAULT_WORKSPACE_ID = "workspace-default";
7
8
  const INITIAL_WORKSPACE_ID = DEFAULT_WORKSPACE_ID;
8
9
  export class ControlStore {
@@ -18,7 +19,7 @@ export class ControlStore {
18
19
  this.migrate();
19
20
  if (bootNonce !== null) {
20
21
  this.reconcilePriorBootGenerations(bootNonce);
21
- this.reconcilePriorBootForegroundTerminalLeases(bootNonce);
22
+ this.reconcilePriorBootLaunchInstances(bootNonce);
22
23
  }
23
24
  }
24
25
  catch (error) {
@@ -29,8 +30,8 @@ export class ControlStore {
29
30
  migrate() {
30
31
  const versionRow = this.database.prepare("PRAGMA user_version").get();
31
32
  const version = versionRow.user_version;
32
- if (version > 4)
33
- throw new Error(`control database version ${version} is newer than supported version 4`);
33
+ if (version > 5)
34
+ throw new Error(`control database version ${version} is newer than supported version 5`);
34
35
  if (version !== 0)
35
36
  this.#assertCurrentControlSchema();
36
37
  if (version === 0) {
@@ -172,6 +173,41 @@ export class ControlStore {
172
173
  ALTER TABLE workspaces ADD COLUMN revision INTEGER NOT NULL DEFAULT 0 CHECK (revision >= 0);
173
174
  PRAGMA user_version = 4;
174
175
  COMMIT;
176
+ `);
177
+ }
178
+ if (version <= 4) {
179
+ this.database.exec(`
180
+ BEGIN IMMEDIATE;
181
+ UPDATE foreground_terminal_leases
182
+ SET state = 'interrupted',
183
+ released_at = COALESCE(released_at, strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
184
+ outcome_json = '{"kind":"interrupted","reason":"legacy-migration","message":"legacy foreground ownership cannot prove current launch-instance liveness"}'
185
+ WHERE state IN ('requested', 'active');
186
+ DROP INDEX IF EXISTS idx_one_live_foreground_lease;
187
+ CREATE TABLE launch_instances (
188
+ id TEXT PRIMARY KEY,
189
+ owner_client_id TEXT NOT NULL,
190
+ profile_id TEXT NOT NULL CHECK (profile_id IN ('a1', 'pi', 'sandbox')),
191
+ state TEXT NOT NULL CHECK (state IN ('requested', 'active', 'stopping', 'completed', 'interrupted')),
192
+ shutdown_policy TEXT NOT NULL CHECK (shutdown_policy = 'terminate-tree-on-close'),
193
+ guardian_identity_json TEXT NOT NULL CHECK (json_valid(guardian_identity_json)),
194
+ root_identity_json TEXT CHECK (root_identity_json IS NULL OR json_valid(root_identity_json)),
195
+ containment_identity_json TEXT CHECK (containment_identity_json IS NULL OR json_valid(containment_identity_json)),
196
+ created_at TEXT NOT NULL,
197
+ activated_at TEXT,
198
+ stopping_at TEXT,
199
+ completed_at TEXT,
200
+ outcome_json TEXT CHECK (outcome_json IS NULL OR json_valid(outcome_json)),
201
+ owner_boot_nonce TEXT NOT NULL,
202
+ CHECK ((state = 'requested' AND root_identity_json IS NULL AND containment_identity_json IS NULL AND activated_at IS NULL AND stopping_at IS NULL AND completed_at IS NULL AND outcome_json IS NULL)
203
+ OR (state = 'active' AND root_identity_json IS NOT NULL AND containment_identity_json IS NOT NULL AND activated_at IS NOT NULL AND stopping_at IS NULL AND completed_at IS NULL AND outcome_json IS NULL)
204
+ OR (state = 'stopping' AND root_identity_json IS NOT NULL AND containment_identity_json IS NOT NULL AND activated_at IS NOT NULL AND stopping_at IS NOT NULL AND completed_at IS NULL AND outcome_json IS NULL)
205
+ OR (state IN ('completed', 'interrupted') AND completed_at IS NOT NULL AND outcome_json IS NOT NULL))
206
+ );
207
+ CREATE INDEX idx_launch_instances_owner ON launch_instances(owner_client_id, state);
208
+ CREATE INDEX idx_launch_instances_boot ON launch_instances(owner_boot_nonce, state);
209
+ PRAGMA user_version = 5;
210
+ COMMIT;
175
211
  `);
176
212
  }
177
213
  if (version === 0) {
@@ -199,61 +235,70 @@ export class ControlStore {
199
235
  return Number(result.changes);
200
236
  });
201
237
  }
202
- acquireForegroundTerminalLease(lease) {
238
+ createLaunchInstance(instance) {
203
239
  if (this.bootNonce === null)
204
- throw new Error("foreground lease storage requires a supervisor boot identity");
205
- if (lease.state !== "requested" || lease.generationId !== null || lease.processIdentity !== null || lease.releasedAt !== null || lease.outcome !== null) {
206
- throw new Error("new foreground lease must be requested and unactivated");
207
- }
208
- try {
209
- this.database.prepare(`INSERT INTO foreground_terminal_leases
210
- (id, owner_id, profile_json, state, generation_id, process_identity_json, acquired_at, heartbeat_at, released_at, outcome_json, owner_boot_nonce)
211
- VALUES (?, ?, ?, 'requested', NULL, NULL, ?, NULL, NULL, NULL, ?)`)
212
- .run(lease.id, lease.ownerId, JSON.stringify(lease.profile), lease.acquiredAt, this.bootNonce);
213
- }
214
- catch (error) {
215
- if (error instanceof Error && /UNIQUE constraint failed/i.test(error.message))
216
- throw new Error("an exclusive foreground terminal lease is already live");
217
- throw error;
218
- }
240
+ throw new Error("launch instance storage requires a supervisor boot identity");
241
+ assertLaunchInstance(instance);
242
+ if (instance.state !== "requested")
243
+ throw new Error("new launch instance must be requested");
244
+ this.database.prepare(`INSERT INTO launch_instances
245
+ (id, owner_client_id, profile_id, state, shutdown_policy, guardian_identity_json, root_identity_json, containment_identity_json,
246
+ created_at, activated_at, stopping_at, completed_at, outcome_json, owner_boot_nonce)
247
+ VALUES (?, ?, ?, 'requested', ?, ?, NULL, NULL, ?, NULL, NULL, NULL, NULL, ?)`)
248
+ .run(instance.id, instance.ownerClientId, instance.profileId, instance.shutdownPolicy, JSON.stringify(instance.guardianIdentity), instance.createdAt, this.bootNonce);
219
249
  }
220
- activateForegroundTerminalLease(leaseId, generationId, processIdentity, heartbeatAt) {
250
+ activateLaunchInstance(instanceId, ownerClientId, rootIdentity, containmentIdentity, activatedAt) {
221
251
  if (this.bootNonce === null)
222
- throw new Error("foreground lease storage requires a supervisor boot identity");
223
- const result = this.database.prepare(`UPDATE foreground_terminal_leases
224
- SET state = 'active', generation_id = ?, process_identity_json = ?, heartbeat_at = ?
225
- WHERE id = ? AND state = 'requested' AND owner_boot_nonce = ?`)
226
- .run(generationId, JSON.stringify(processIdentity), heartbeatAt, leaseId, this.bootNonce);
252
+ throw new Error("launch instance storage requires a supervisor boot identity");
253
+ assertNativeProcessIdentity(rootIdentity);
254
+ assertProcessContainmentIdentity(containmentIdentity);
255
+ const result = this.database.prepare(`UPDATE launch_instances
256
+ SET state = 'active', root_identity_json = ?, containment_identity_json = ?, activated_at = ?
257
+ WHERE id = ? AND owner_client_id = ? AND owner_boot_nonce = ? AND state = 'requested'`)
258
+ .run(JSON.stringify(rootIdentity), JSON.stringify(containmentIdentity), activatedAt, instanceId, ownerClientId, this.bootNonce);
227
259
  return Number(result.changes) === 1;
228
260
  }
229
- heartbeatForegroundTerminalLease(leaseId, processIdentity, heartbeatAt) {
261
+ beginLaunchInstanceStop(instanceId, ownerClientId, stoppingAt) {
230
262
  if (this.bootNonce === null)
231
- throw new Error("foreground lease storage requires a supervisor boot identity");
232
- const result = this.database.prepare(`UPDATE foreground_terminal_leases SET heartbeat_at = ?
233
- WHERE id = ? AND state = 'active' AND owner_boot_nonce = ? AND process_identity_json = ?`)
234
- .run(heartbeatAt, leaseId, this.bootNonce, JSON.stringify(processIdentity));
263
+ throw new Error("launch instance storage requires a supervisor boot identity");
264
+ const result = this.database.prepare(`UPDATE launch_instances SET state = 'stopping', stopping_at = ?
265
+ WHERE id = ? AND owner_client_id = ? AND owner_boot_nonce = ? AND state = 'active'`)
266
+ .run(stoppingAt, instanceId, ownerClientId, this.bootNonce);
235
267
  return Number(result.changes) === 1;
236
268
  }
237
- releaseForegroundTerminalLease(leaseId, processIdentity, outcome, releasedAt) {
269
+ completeLaunchInstance(instanceId, ownerClientId, terminalState, outcome, completedAt) {
238
270
  if (this.bootNonce === null)
239
- throw new Error("foreground lease storage requires a supervisor boot identity");
240
- const expectedIdentity = processIdentity === null ? null : JSON.stringify(processIdentity);
241
- const result = this.database.prepare(`UPDATE foreground_terminal_leases
242
- SET state = 'released', released_at = ?, outcome_json = ?
243
- WHERE id = ? AND state IN ('requested', 'active') AND owner_boot_nonce = ?
244
- AND ((process_identity_json IS NULL AND ? IS NULL) OR process_identity_json = ?)`)
245
- .run(releasedAt, JSON.stringify(outcome), leaseId, this.bootNonce, expectedIdentity, expectedIdentity);
271
+ throw new Error("launch instance storage requires a supervisor boot identity");
272
+ assertLaunchInstanceOutcome(outcome);
273
+ if (terminalState === "completed" && outcome.kind === "interrupted")
274
+ throw new Error("completed launch instance cannot carry an interrupted outcome");
275
+ if (terminalState === "interrupted" && outcome.kind !== "interrupted" && outcome.kind !== "cleanup-error") {
276
+ throw new Error("interrupted launch instance requires an interrupted or cleanup-error outcome");
277
+ }
278
+ const result = this.database.prepare(`UPDATE launch_instances
279
+ SET state = ?, completed_at = ?, outcome_json = ?
280
+ WHERE id = ? AND owner_client_id = ? AND owner_boot_nonce = ? AND state IN ('requested', 'active', 'stopping')`)
281
+ .run(terminalState, completedAt, JSON.stringify(outcome), instanceId, ownerClientId, this.bootNonce);
246
282
  return Number(result.changes) === 1;
247
283
  }
248
- loadLiveForegroundTerminalLease() {
249
- const row = this.database.prepare("SELECT * FROM foreground_terminal_leases WHERE state IN ('requested', 'active') LIMIT 1").get();
250
- return row ? foregroundLeaseFromRow(row) : null;
284
+ loadActiveLaunchInstances() {
285
+ return this.database.prepare(`SELECT * FROM launch_instances
286
+ WHERE state IN ('requested', 'active', 'stopping') ORDER BY created_at, id`).all()
287
+ .map(launchInstanceFromRow);
251
288
  }
252
- reconcilePriorBootForegroundTerminalLeases(bootNonce, reconciledAt = new Date().toISOString()) {
253
- const outcome = { kind: "broker-error", message: "foreground lease owner ended before a terminal outcome", code: "stale-owner-boot" };
254
- const result = this.database.prepare(`UPDATE foreground_terminal_leases
255
- SET state = 'released', released_at = ?, outcome_json = ?
256
- WHERE state IN ('requested', 'active') AND owner_boot_nonce <> ?`)
289
+ loadLaunchInstance(instanceId) {
290
+ const row = this.database.prepare("SELECT * FROM launch_instances WHERE id = ?").get(instanceId);
291
+ return row ? launchInstanceFromRow(row) : null;
292
+ }
293
+ reconcilePriorBootLaunchInstances(bootNonce, reconciledAt = new Date().toISOString()) {
294
+ const outcome = {
295
+ kind: "interrupted",
296
+ reason: "supervisor-disconnect",
297
+ message: "launch instance ownership ended with a prior supervisor boot",
298
+ };
299
+ const result = this.database.prepare(`UPDATE launch_instances
300
+ SET state = 'interrupted', completed_at = ?, outcome_json = ?
301
+ WHERE state IN ('requested', 'active', 'stopping') AND owner_boot_nonce <> ?`)
257
302
  .run(reconciledAt, JSON.stringify(outcome), bootNonce);
258
303
  return Number(result.changes);
259
304
  }
@@ -464,17 +509,22 @@ function assertWorkspaceAgentPresentation(presentation) {
464
509
  }
465
510
  }
466
511
  }
467
- function foregroundLeaseFromRow(row) {
468
- return {
512
+ function launchInstanceFromRow(row) {
513
+ const instance = {
469
514
  id: row.id,
470
- ownerId: row.owner_id,
471
- profile: JSON.parse(row.profile_json),
515
+ ownerClientId: row.owner_client_id,
516
+ profileId: row.profile_id,
472
517
  state: row.state,
473
- generationId: row.generation_id,
474
- processIdentity: row.process_identity_json ? JSON.parse(row.process_identity_json) : null,
475
- acquiredAt: row.acquired_at,
476
- heartbeatAt: row.heartbeat_at,
477
- releasedAt: row.released_at,
518
+ shutdownPolicy: row.shutdown_policy,
519
+ guardianIdentity: JSON.parse(row.guardian_identity_json),
520
+ rootIdentity: row.root_identity_json ? JSON.parse(row.root_identity_json) : null,
521
+ containmentIdentity: row.containment_identity_json ? JSON.parse(row.containment_identity_json) : null,
522
+ createdAt: row.created_at,
523
+ activatedAt: row.activated_at,
524
+ stoppingAt: row.stopping_at,
525
+ completedAt: row.completed_at,
478
526
  outcome: row.outcome_json ? JSON.parse(row.outcome_json) : null,
479
527
  };
528
+ assertLaunchInstance(instance);
529
+ return instance;
480
530
  }
@@ -1,5 +1,5 @@
1
1
  import { type SupervisorSnapshot } from "../lifecycle/index.js";
2
- import type { MaterializedRelease } from "../release/index.js";
2
+ import { type MaterializedRelease } from "../release/index.js";
3
3
  import { ControlStore } from "../storage/index.js";
4
4
  import { type ProductPaths } from "./paths.js";
5
5
  export declare class SupervisorServer {
@@ -7,12 +7,14 @@ export declare class SupervisorServer {
7
7
  readonly store: ControlStore;
8
8
  readonly release: MaterializedRelease;
9
9
  readonly terminateProcess: (code: number) => void;
10
+ readonly reconciliationDeadlineMs: number;
11
+ readonly shutdownDeadlineMs: number;
10
12
  readonly id: `${string}-${string}-${string}-${string}-${string}`;
11
13
  readonly bootNonce: string;
12
14
  readonly pidStartIdentity: string;
13
15
  readonly startedAt: string;
14
16
  readonly paths: ProductPaths;
15
- constructor(store: ControlStore, paths: ProductPaths | undefined, release: MaterializedRelease, bootNonce?: string, terminateProcess?: (code: number) => void);
17
+ constructor(store: ControlStore, paths: ProductPaths | undefined, release: MaterializedRelease, bootNonce?: string, terminateProcess?: (code: number) => void, reconciliationDeadlineMs?: number, shutdownDeadlineMs?: number);
16
18
  snapshot(): SupervisorSnapshot;
17
19
  listen(): Promise<void>;
18
20
  close(stopAgents?: boolean): Promise<void>;