@timurproko/a1 0.2.7-dev.1245 → 0.2.7-dev.1252

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 (342) hide show
  1. package/README.md +11 -36
  2. package/bin/cli.js +2 -17
  3. package/bin/ui.js +7 -48
  4. package/dist/app/session-shell/exit-notice.d.ts +2 -2
  5. package/dist/app/session-shell/exit-notice.js +10 -10
  6. package/dist/app/session-shell/prompt-submission.d.ts +2 -4
  7. package/dist/app/session-shell/prompt-submission.js +3 -23
  8. package/dist/app/session-shell/response-copy-transport.js +1 -2
  9. package/dist/app/session-shell/session-lifecycle.d.ts +1 -2
  10. package/dist/app/session-shell/session-lifecycle.js +2 -4
  11. package/dist/app/session-shell/session-shell-root.d.ts +0 -31
  12. package/dist/app/session-shell/session-shell-root.js +3 -4
  13. package/dist/app/session-shell/session-shell.js +6 -47
  14. package/dist/app/session-shell/session-viewport-controller.js +3 -6
  15. package/dist/app/session-shell/shell-host.js +2 -18
  16. package/dist/app/session-shell/transcript-document.d.ts +1 -2
  17. package/dist/app/session-shell/transcript-document.js +3 -28
  18. package/dist/app/session-shell/workflow-output.js +1 -1
  19. package/dist/app/session-shell/workflow-router.d.ts +1 -3
  20. package/dist/app/session-shell/workflow-router.js +1 -4
  21. package/dist/cli/dispatch.d.ts +1 -11
  22. package/dist/cli/dispatch.js +5 -92
  23. package/dist/cli/session-context.js +5 -7
  24. package/dist/cli/uninstall.d.ts +1 -5
  25. package/dist/cli/uninstall.js +6 -35
  26. package/dist/cli/version-stats.js +4 -7
  27. package/dist/composition/owned-settings.d.ts +0 -1
  28. package/dist/composition/owned-settings.js +0 -1
  29. package/dist/composition/owned-ui.d.ts +2 -24
  30. package/dist/composition/owned-ui.js +11 -87
  31. package/dist/composition/release-update-observation.d.ts +4 -4
  32. package/dist/composition/release-update-observation.js +17 -47
  33. package/dist/composition/session-backend.d.ts +0 -1
  34. package/dist/composition/session-runtime-registry.d.ts +3 -3
  35. package/dist/composition/settings-route-host.d.ts +0 -7
  36. package/dist/composition/settings-route-host.js +4 -10
  37. package/dist/composition/startup-route.d.ts +0 -1
  38. package/dist/composition/startup-route.js +0 -1
  39. package/dist/contracts/owned-ui/index.d.ts +1 -1
  40. package/dist/contracts/owned-ui/model.d.ts +0 -3
  41. package/dist/contracts/owned-ui/session-workflows.d.ts +1 -4
  42. package/dist/features/launch/development-launch.js +0 -1
  43. package/dist/features/launch/index.d.ts +1 -1
  44. package/dist/features/launch/intent.d.ts +1 -3
  45. package/dist/features/launch/intent.js +2 -4
  46. package/dist/features/launch/session-context.d.ts +2 -2
  47. package/dist/features/owned-ui/reference-screen-app.d.ts +0 -2
  48. package/dist/features/owned-ui/reference-screen-app.js +2 -9
  49. package/dist/features/owned-ui/settings-app.d.ts +0 -6
  50. package/dist/features/owned-ui/settings-app.js +5 -36
  51. package/dist/foundation/launch-context/index.d.ts +0 -12
  52. package/dist/foundation/launch-context/index.js +0 -26
  53. package/dist/foundation/lifecycle/claim-gate.d.ts +8 -0
  54. package/dist/foundation/lifecycle/claim-gate.js +37 -0
  55. package/dist/foundation/lifecycle/index.d.ts +5 -9
  56. package/dist/foundation/lifecycle/index.js +3 -4
  57. package/dist/foundation/lifecycle/model.d.ts +2 -59
  58. package/dist/foundation/lifecycle/model.js +0 -35
  59. package/dist/foundation/lifecycle/paths.d.ts +0 -24
  60. package/dist/foundation/lifecycle/paths.js +0 -40
  61. package/dist/foundation/lifecycle/process-liveness.d.ts +8 -0
  62. package/dist/foundation/lifecycle/process-liveness.js +18 -0
  63. package/dist/foundation/lifecycle/session-claim-lock.d.ts +1 -1
  64. package/dist/foundation/lifecycle/session-claim-lock.js +2 -2
  65. package/dist/foundation/lifecycle/session-repository-context.d.ts +6 -6
  66. package/dist/foundation/lifecycle/session-repository-context.js +2 -3
  67. package/dist/foundation/release/automatic-update.d.ts +1 -3
  68. package/dist/foundation/release/automatic-update.js +9 -30
  69. package/dist/foundation/release/bootstrap.d.ts +2 -25
  70. package/dist/foundation/release/bootstrap.js +33 -344
  71. package/dist/foundation/release/cohort-state.d.ts +21 -46
  72. package/dist/foundation/release/cohort-state.js +30 -62
  73. package/dist/foundation/release/dependency-certification.d.ts +1 -1
  74. package/dist/foundation/release/index.d.ts +10 -17
  75. package/dist/foundation/release/index.js +7 -11
  76. package/dist/foundation/release/latest-release.d.ts +1 -2
  77. package/dist/foundation/release/latest-release.js +1 -2
  78. package/dist/foundation/release/process-liveness.d.ts +2 -0
  79. package/dist/foundation/release/process-liveness.js +12 -0
  80. package/dist/foundation/release/release-gc.d.ts +12 -9
  81. package/dist/foundation/release/release-gc.js +34 -98
  82. package/dist/foundation/release/release-store.d.ts +2 -2
  83. package/dist/foundation/release/release-store.js +2 -2
  84. package/dist/foundation/release/restart-certification.js +1 -1
  85. package/dist/foundation/release/update-activation.d.ts +2 -9
  86. package/dist/foundation/release/update-activation.js +28 -43
  87. package/dist/foundation/release/update-execution-lease.js +1 -1
  88. package/dist/foundation/release/update-launch.d.ts +0 -2
  89. package/dist/foundation/release/update-launch.js +0 -7
  90. package/dist/foundation/release/update-recovery.js +1 -1
  91. package/dist/foundation/release/update-transaction.d.ts +1 -1
  92. package/dist/foundation/release/update-transaction.js +5 -2
  93. package/dist/foundation/release/update.d.ts +2 -10
  94. package/dist/foundation/release/update.js +23 -200
  95. package/dist/foundation/session-writer-lock/index.d.ts +14 -6
  96. package/dist/foundation/session-writer-lock/index.js +48 -103
  97. package/dist/foundation/startup/startup-runtime.d.ts +1 -1
  98. package/dist/foundation/terminal-cleanup/exit-notice.d.ts +6 -0
  99. package/dist/foundation/terminal-cleanup/exit-notice.js +36 -0
  100. package/dist/foundation/terminal-cleanup/index.d.ts +2 -1
  101. package/dist/foundation/terminal-cleanup/index.js +2 -1
  102. package/dist/foundation/terminal-cleanup/terminal-reset.d.ts +0 -5
  103. package/dist/foundation/terminal-cleanup/terminal-reset.js +0 -5
  104. package/dist/integrations/pi/components/index.d.ts +1 -1
  105. package/dist/integrations/pi/components/index.js +1 -1
  106. package/dist/integrations/pi/components/shell-editor-autocomplete.js +1 -4
  107. package/dist/integrations/pi/components/shell-footer-status.d.ts +1 -1
  108. package/dist/integrations/pi/components/shell-footer-status.js +2 -2
  109. package/dist/integrations/pi/components/shell-hotkey-sections.js +1 -1
  110. package/dist/integrations/pi/components/shell-presenters-info.d.ts +2 -5
  111. package/dist/integrations/pi/components/shell-presenters-info.js +4 -18
  112. package/dist/integrations/pi/components/shell-presenters-transcript.d.ts +1 -1
  113. package/dist/integrations/pi/components/shell-presenters-transcript.js +1 -1
  114. package/dist/integrations/pi/components/shell-shared-facade.d.ts +0 -2
  115. package/dist/integrations/pi/components/submitted-prompt-adapter.d.ts +2 -5
  116. package/dist/integrations/pi/components/submitted-prompt-adapter.js +2 -16
  117. package/dist/integrations/pi/components/upstream/components/session-footer.d.ts +1 -2
  118. package/dist/integrations/pi/components/upstream/components/session-footer.js +6 -8
  119. package/dist/integrations/pi/engine/adapter.d.ts +0 -1
  120. package/dist/integrations/pi/engine/adapter.js +1 -16
  121. package/dist/integrations/pi/engine/compaction-progress.js +13 -5
  122. package/dist/integrations/pi/engine/diagnostics-state.d.ts +0 -1
  123. package/dist/integrations/pi/engine/diagnostics-state.js +0 -14
  124. package/dist/integrations/pi/engine/prompt-suggestions.d.ts +0 -1
  125. package/dist/integrations/pi/engine/prompt-suggestions.js +0 -40
  126. package/dist/integrations/pi/engine/session-runtime.js +0 -2
  127. package/dist/integrations/pi/engine/workflow-runner.js +1 -1
  128. package/dist/integrations/pi/tui-runtime/adapter.d.ts +2 -2
  129. package/dist/integrations/pi/tui-runtime/adapter.js +2 -2
  130. package/dist/product-identity.d.ts +4 -6
  131. package/dist/product-identity.js +6 -11
  132. package/dist/product-identity.json +1 -40
  133. package/dist/runtime-payload-inventory.json +0 -3
  134. package/dist/ui/components/index.d.ts +2 -2
  135. package/dist/ui/components/index.js +1 -1
  136. package/dist/ui/components/submitted-prompt.d.ts +3 -13
  137. package/dist/ui/components/submitted-prompt.js +8 -41
  138. package/dist/ui/components/transcript-viewport.d.ts +1 -3
  139. package/dist/ui/components/transcript-viewport.js +1 -4
  140. package/dist/ui/settings/declarations.d.ts +3 -97
  141. package/dist/ui/settings/declarations.js +3 -78
  142. package/dist/ui/settings/migrations.js +18 -2
  143. package/docs/architecture/boundaries.md +22 -39
  144. package/docs/architecture/code-documentation.md +2 -2
  145. package/docs/architecture/internal-naming.md +9 -17
  146. package/docs/architecture/project-structure.md +30 -29
  147. package/docs/architecture/resource-and-data-policy.md +16 -31
  148. package/docs/architecture/toolchain.md +14 -19
  149. package/docs/architecture/ui-reference-provenance.md +2 -2
  150. package/docs/ci-release-runbook.md +6 -4
  151. package/docs/features/launch-profiles.md +11 -17
  152. package/docs/features/prompt-history.md +10 -11
  153. package/docs/local-worktree-cleanup.md +32 -1
  154. package/docs/manual-owned-ui-checkpoint.md +0 -1
  155. package/docs/openspec-archive-automation.md +11 -3
  156. package/docs/validation.md +5 -9
  157. package/docs/worktree-link-recovery.md +6 -6
  158. package/package.json +7 -19
  159. package/bin/guardian.js +0 -42
  160. package/bin/supervisor.js +0 -7
  161. package/bin/tab-launch-context.d.ts +0 -27
  162. package/bin/tab-launch-context.js +0 -94
  163. package/dist/app/session-shell/resident-tab-coordinator.d.ts +0 -38
  164. package/dist/app/session-shell/resident-tab-coordinator.js +0 -77
  165. package/dist/cli/tabs-request.d.ts +0 -7
  166. package/dist/cli/tabs-request.js +0 -1
  167. package/dist/cli/tabs.d.ts +0 -14
  168. package/dist/cli/tabs.js +0 -151
  169. package/dist/composition/resident-tab-bridge.d.ts +0 -41
  170. package/dist/composition/resident-tab-bridge.js +0 -209
  171. package/dist/composition/utility-tab.d.ts +0 -28
  172. package/dist/composition/utility-tab.js +0 -244
  173. package/dist/features/owned-ui/plus-menu-dialog.d.ts +0 -28
  174. package/dist/features/owned-ui/plus-menu-dialog.js +0 -89
  175. package/dist/features/resident-tab/auto-name.d.ts +0 -11
  176. package/dist/features/resident-tab/auto-name.js +0 -44
  177. package/dist/features/resident-tab/index.d.ts +0 -5
  178. package/dist/features/resident-tab/index.js +0 -7
  179. package/dist/features/resident-tab/shortcut-bindings-file.d.ts +0 -8
  180. package/dist/features/resident-tab/shortcut-bindings-file.js +0 -40
  181. package/dist/features/resident-tab/shortcut-declarations.d.ts +0 -13
  182. package/dist/features/resident-tab/shortcut-declarations.js +0 -26
  183. package/dist/features/resident-tab/shortcut-projection.d.ts +0 -29
  184. package/dist/features/resident-tab/shortcut-projection.js +0 -64
  185. package/dist/features/resident-tab/status-deriver.d.ts +0 -10
  186. package/dist/features/resident-tab/status-deriver.js +0 -12
  187. package/dist/foundation/launch-guardian/exit-watcher.d.ts +0 -14
  188. package/dist/foundation/launch-guardian/exit-watcher.js +0 -103
  189. package/dist/foundation/launch-guardian/index.d.ts +0 -2
  190. package/dist/foundation/launch-guardian/index.js +0 -1
  191. package/dist/foundation/launch-guardian/main.d.ts +0 -39
  192. package/dist/foundation/launch-guardian/main.js +0 -232
  193. package/dist/foundation/lifecycle/commands.d.ts +0 -40
  194. package/dist/foundation/lifecycle/commands.js +0 -1
  195. package/dist/foundation/lifecycle/launch-instance.d.ts +0 -46
  196. package/dist/foundation/lifecycle/launch-instance.js +0 -134
  197. package/dist/foundation/lifecycle/native-claim-gate.d.ts +0 -5
  198. package/dist/foundation/lifecycle/native-claim-gate.js +0 -41
  199. package/dist/foundation/lifecycle/supervisor-startup.d.ts +0 -30
  200. package/dist/foundation/lifecycle/supervisor-startup.js +0 -106
  201. package/dist/foundation/process-containment/addon-containment.d.ts +0 -20
  202. package/dist/foundation/process-containment/addon-containment.js +0 -139
  203. package/dist/foundation/process-containment/addon-process-inspector.d.ts +0 -11
  204. package/dist/foundation/process-containment/addon-process-inspector.js +0 -36
  205. package/dist/foundation/process-containment/addon.d.ts +0 -47
  206. package/dist/foundation/process-containment/addon.js +0 -57
  207. package/dist/foundation/process-containment/artifact.d.ts +0 -1
  208. package/dist/foundation/process-containment/artifact.js +0 -35
  209. package/dist/foundation/process-containment/contracts.d.ts +0 -33
  210. package/dist/foundation/process-containment/contracts.js +0 -35
  211. package/dist/foundation/process-containment/index.d.ts +0 -9
  212. package/dist/foundation/process-containment/index.js +0 -7
  213. package/dist/foundation/process-containment/linux-process-inspector.d.ts +0 -7
  214. package/dist/foundation/process-containment/linux-process-inspector.js +0 -27
  215. package/dist/foundation/process-containment/native-process-inspector.d.ts +0 -4
  216. package/dist/foundation/process-containment/native-process-inspector.js +0 -21
  217. package/dist/foundation/protocol/client.d.ts +0 -18
  218. package/dist/foundation/protocol/client.js +0 -130
  219. package/dist/foundation/protocol/index.d.ts +0 -3
  220. package/dist/foundation/protocol/index.js +0 -2
  221. package/dist/foundation/protocol/messages.d.ts +0 -90
  222. package/dist/foundation/protocol/messages.js +0 -100
  223. package/dist/foundation/release/cohort-selection.d.ts +0 -33
  224. package/dist/foundation/release/cohort-selection.js +0 -67
  225. package/dist/foundation/release/endpoint-lock.d.ts +0 -2
  226. package/dist/foundation/release/endpoint-lock.js +0 -37
  227. package/dist/foundation/release/endpoint-recovery.d.ts +0 -10
  228. package/dist/foundation/release/endpoint-recovery.js +0 -45
  229. package/dist/foundation/release/endpoints.d.ts +0 -32
  230. package/dist/foundation/release/endpoints.js +0 -152
  231. package/dist/foundation/release/prepared-update-activation.d.ts +0 -3
  232. package/dist/foundation/release/prepared-update-activation.js +0 -27
  233. package/dist/foundation/release/process-cleanup.d.ts +0 -14
  234. package/dist/foundation/release/process-cleanup.js +0 -76
  235. package/dist/foundation/release/supervisor-identity.d.ts +0 -15
  236. package/dist/foundation/release/supervisor-identity.js +0 -63
  237. package/dist/foundation/resident-tabs/boot-identity.d.ts +0 -6
  238. package/dist/foundation/resident-tabs/boot-identity.js +0 -16
  239. package/dist/foundation/resident-tabs/bounded-host-command.d.ts +0 -20
  240. package/dist/foundation/resident-tabs/bounded-host-command.js +0 -62
  241. package/dist/foundation/resident-tabs/bridge-client.d.ts +0 -73
  242. package/dist/foundation/resident-tabs/bridge-client.js +0 -327
  243. package/dist/foundation/resident-tabs/continuity.d.ts +0 -12
  244. package/dist/foundation/resident-tabs/continuity.js +0 -63
  245. package/dist/foundation/resident-tabs/doctor.d.ts +0 -28
  246. package/dist/foundation/resident-tabs/doctor.js +0 -166
  247. package/dist/foundation/resident-tabs/draft-checkpoint.d.ts +0 -27
  248. package/dist/foundation/resident-tabs/draft-checkpoint.js +0 -145
  249. package/dist/foundation/resident-tabs/ensure-terminal-host.d.ts +0 -36
  250. package/dist/foundation/resident-tabs/ensure-terminal-host.js +0 -151
  251. package/dist/foundation/resident-tabs/fault-injection.d.ts +0 -8
  252. package/dist/foundation/resident-tabs/fault-injection.js +0 -26
  253. package/dist/foundation/resident-tabs/fixture-control.d.ts +0 -7
  254. package/dist/foundation/resident-tabs/fixture-control.js +0 -35
  255. package/dist/foundation/resident-tabs/host-entry.d.ts +0 -1
  256. package/dist/foundation/resident-tabs/host-entry.js +0 -17
  257. package/dist/foundation/resident-tabs/index.d.ts +0 -15
  258. package/dist/foundation/resident-tabs/index.js +0 -10
  259. package/dist/foundation/resident-tabs/maintenance.d.ts +0 -39
  260. package/dist/foundation/resident-tabs/maintenance.js +0 -75
  261. package/dist/foundation/resident-tabs/progress-observation-schema.d.ts +0 -34
  262. package/dist/foundation/resident-tabs/progress-observation-schema.js +0 -1
  263. package/dist/foundation/resident-tabs/progress-observation.d.ts +0 -4
  264. package/dist/foundation/resident-tabs/progress-observation.js +0 -150
  265. package/dist/foundation/resident-tabs/prompt-journal.d.ts +0 -63
  266. package/dist/foundation/resident-tabs/prompt-journal.js +0 -213
  267. package/dist/foundation/resident-tabs/protocol.d.ts +0 -12
  268. package/dist/foundation/resident-tabs/protocol.js +0 -195
  269. package/dist/foundation/resident-tabs/recovery.d.ts +0 -26
  270. package/dist/foundation/resident-tabs/recovery.js +0 -205
  271. package/dist/foundation/resident-tabs/release-holds.d.ts +0 -28
  272. package/dist/foundation/resident-tabs/release-holds.js +0 -78
  273. package/dist/foundation/resident-tabs/routes.d.ts +0 -5
  274. package/dist/foundation/resident-tabs/routes.js +0 -5
  275. package/dist/foundation/resident-tabs/routing.d.ts +0 -11
  276. package/dist/foundation/resident-tabs/routing.js +0 -10
  277. package/dist/foundation/resident-tabs/runtime-control.d.ts +0 -38
  278. package/dist/foundation/resident-tabs/runtime-control.js +0 -74
  279. package/dist/foundation/resident-tabs/session-sync.d.ts +0 -14
  280. package/dist/foundation/resident-tabs/session-sync.js +0 -37
  281. package/dist/foundation/resident-tabs/settings.d.ts +0 -16
  282. package/dist/foundation/resident-tabs/settings.js +0 -60
  283. package/dist/foundation/resident-tabs/terminal-host-artifact.d.ts +0 -14
  284. package/dist/foundation/resident-tabs/terminal-host-artifact.js +0 -78
  285. package/dist/foundation/resident-tabs/zip-archive.d.ts +0 -9
  286. package/dist/foundation/resident-tabs/zip-archive.js +0 -56
  287. package/dist/foundation/storage/control-store.d.ts +0 -20
  288. package/dist/foundation/storage/control-store.js +0 -331
  289. package/dist/foundation/storage/index.d.ts +0 -1
  290. package/dist/foundation/storage/index.js +0 -1
  291. package/dist/foundation/supervision/index.d.ts +0 -3
  292. package/dist/foundation/supervision/index.js +0 -3
  293. package/dist/foundation/supervision/main.d.ts +0 -1
  294. package/dist/foundation/supervision/main.js +0 -86
  295. package/dist/foundation/supervision/paths.d.ts +0 -1
  296. package/dist/foundation/supervision/paths.js +0 -1
  297. package/dist/foundation/supervision/server.d.ts +0 -46
  298. package/dist/foundation/supervision/server.js +0 -606
  299. package/dist/integrations/pi/engine/offline-settings-port.d.ts +0 -23
  300. package/dist/integrations/pi/engine/offline-settings-port.js +0 -54
  301. package/dist/native/darwin-arm64/manifest.json +0 -23
  302. package/dist/native/darwin-arm64/process-guardian.node +0 -0
  303. package/dist/native/darwin-arm64/terminal-host-THIRD-PARTY-NOTICES.txt +0 -10500
  304. package/dist/native/darwin-arm64/terminal-host.manifest.json +0 -46
  305. package/dist/native/darwin-arm64/terminal-host.node +0 -0
  306. package/dist/native/darwin-x64/manifest.json +0 -23
  307. package/dist/native/darwin-x64/process-guardian.node +0 -0
  308. package/dist/native/darwin-x64/terminal-host-THIRD-PARTY-NOTICES.txt +0 -10737
  309. package/dist/native/darwin-x64/terminal-host.manifest.json +0 -46
  310. package/dist/native/darwin-x64/terminal-host.node +0 -0
  311. package/dist/native/linux-x64/manifest.json +0 -23
  312. package/dist/native/linux-x64/process-guardian.node +0 -0
  313. package/dist/native/linux-x64/terminal-host-THIRD-PARTY-NOTICES.txt +0 -11226
  314. package/dist/native/linux-x64/terminal-host.manifest.json +0 -46
  315. package/dist/native/linux-x64/terminal-host.node +0 -0
  316. package/dist/native/win32-x64/manifest.json +0 -23
  317. package/dist/native/win32-x64/process-guardian.node +0 -0
  318. package/dist/native/win32-x64/terminal-host-THIRD-PARTY-NOTICES.txt +0 -10757
  319. package/dist/native/win32-x64/terminal-host.manifest.json +0 -46
  320. package/dist/native/win32-x64/terminal-host.node +0 -0
  321. package/docs/architecture/evidence/resident-tabs/linux-x64.md +0 -37
  322. package/docs/architecture/evidence/resident-tabs/macos-arm64.md +0 -36
  323. package/docs/architecture/evidence/resident-tabs/macos-x64.md +0 -35
  324. package/docs/architecture/evidence/resident-tabs/windows-x64.md +0 -36
  325. package/docs/architecture/evidence/terminal-host-spike/manual-one-pane-terminal-host.md +0 -70
  326. package/docs/architecture/evidence/terminal-host-spike/manual-two-by-two-basic-terminal-host.md +0 -32
  327. package/docs/architecture/evidence/terminal-host-spike/milestone-baseline.json +0 -115
  328. package/docs/architecture/evidence/terminal-host-spike/owned-ui-foundation-prerequisite.json +0 -48
  329. package/docs/architecture/evidence/terminal-host-spike/terminal-host-provenance.json +0 -125
  330. package/docs/architecture/evidence/terminal-host-spike/terminal-host-task-5-1.json +0 -56
  331. package/docs/architecture/evidence/terminal-host-spike/terminal-host-task-5-3.json +0 -174
  332. package/docs/architecture/evidence/terminal-host-spike/terminal-spike-acceptance-record.json +0 -18
  333. package/docs/architecture/native-fixture-isolation.md +0 -23
  334. package/docs/architecture/process-guardian-provenance.md +0 -36
  335. package/docs/architecture/resident-tabs-requirements.md +0 -18
  336. package/docs/architecture/resident-tabs.md +0 -668
  337. package/docs/architecture/terminal-host-proof-gate.md +0 -34
  338. package/docs/architecture/terminal-host-provenance.md +0 -81
  339. package/docs/architecture/terminal-host-spike-evidence.md +0 -39
  340. package/docs/launch-recovery.md +0 -23
  341. package/docs/manual-launch-instance-acceptance.md +0 -43
  342. package/docs/manual-resident-tabs-acceptance.md +0 -51
@@ -1,27 +0,0 @@
1
- import { readFile } from "node:fs/promises";
2
- /** Verifies Linux process identity from the PID and kernel start-time field in procfs. */
3
- export class LinuxNativeProcessInspector {
4
- async observe(pid) {
5
- if (!Number.isSafeInteger(pid) || pid <= 0)
6
- throw new TypeError("inspected PID must be a positive safe integer");
7
- let stat;
8
- try {
9
- stat = await readFile(`/proc/${pid}/stat`, "utf8");
10
- }
11
- catch (error) {
12
- if (error instanceof Error && "code" in error && error.code === "ENOENT")
13
- return null;
14
- throw error;
15
- }
16
- const commandEnd = stat.lastIndexOf(")");
17
- const fields = commandEnd >= 0 ? stat.slice(commandEnd + 1).trim().split(/\s+/) : [];
18
- const startTicks = fields[19];
19
- if (!startTicks || !/^\d+$/.test(startTicks))
20
- throw new Error("process stat has no valid start-time field");
21
- return { pid, startIdentity: `linux-proc-start:${startTicks}` };
22
- }
23
- async matches(identity) {
24
- const observed = await this.observe(identity.pid);
25
- return observed !== null && observed.startIdentity === identity.startIdentity;
26
- }
27
- }
@@ -1,4 +0,0 @@
1
- import type { ProcessGuardianAddon } from "./addon.js";
2
- import type { NativeProcessInspector } from "./contracts.js";
3
- /** Resolve only the platform's exact-process inspector used by cooperative session ownership. */
4
- export declare function createNativeProcessInspector(environment?: NodeJS.ProcessEnv, platform?: NodeJS.Platform, releaseRoot?: string, loadAddon?: (path: string) => ProcessGuardianAddon): Promise<NativeProcessInspector>;
@@ -1,21 +0,0 @@
1
- import { PRODUCT_IDENTITY } from "../../product-identity.js";
2
- /** Resolve only the platform's exact-process inspector used by cooperative session ownership. */
3
- export async function createNativeProcessInspector(environment = process.env, platform = process.platform, releaseRoot, loadAddon) {
4
- if (platform === "linux") {
5
- const { LinuxNativeProcessInspector } = await import("./linux-process-inspector.js");
6
- return new LinuxNativeProcessInspector();
7
- }
8
- if (platform !== "win32" && platform !== "darwin")
9
- throw new Error(`native process identity is unsupported on ${platform}`);
10
- if (releaseRoot === undefined && !environment[PRODUCT_IDENTITY.environment.processGuardianPath]) {
11
- throw new Error("native process identity addon is unavailable");
12
- }
13
- const [{ resolveProcessGuardianPath }, { loadProcessGuardianAddon }, { AddonProcessInspector }] = await Promise.all([
14
- import("./addon-containment.js"),
15
- import("./addon.js"),
16
- import("./addon-process-inspector.js"),
17
- ]);
18
- const addonPath = resolveProcessGuardianPath(releaseRoot ?? process.cwd(), environment, platform);
19
- const addon = (loadAddon ?? loadProcessGuardianAddon)(addonPath);
20
- return new AddonProcessInspector(addon, platform === "win32" ? "windows-filetime:" : "darwin-proc-start:");
21
- }
@@ -1,18 +0,0 @@
1
- import { EventEmitter } from "node:events";
2
- import type { CommandResult, LaunchInstanceStopIntent, SupervisorCommand, SupervisorSnapshot } from "../lifecycle/index.js";
3
- interface ClientEvents {
4
- snapshot: [SupervisorSnapshot];
5
- stopIntent: [LaunchInstanceStopIntent];
6
- disconnect: [];
7
- }
8
- /** Maintains one negotiated supervisor connection and rejects all pending commands on disconnect. */
9
- export declare class SupervisorClient extends EventEmitter<ClientEvents> {
10
- #private;
11
- readonly clientId: `${string}-${string}-${string}-${string}-${string}`;
12
- readonly releaseId?: string;
13
- constructor(releaseId?: string);
14
- connect(endpoint: string, timeoutMs?: number): Promise<SupervisorSnapshot>;
15
- command(command: SupervisorCommand): Promise<CommandResult>;
16
- close(): void;
17
- }
18
- export {};
@@ -1,130 +0,0 @@
1
- import { EventEmitter } from "node:events";
2
- import { connect } from "node:net";
3
- import { randomUUID } from "node:crypto";
4
- import { CONTROL_ENVELOPE, CONTROL_ENVELOPE_REVISION, encodeFrame, LineFrameDecoder, localControlHello, negotiateControlFeatures } from "./messages.js";
5
- /** Maintains one negotiated supervisor connection and rejects all pending commands on disconnect. */
6
- export class SupervisorClient extends EventEmitter {
7
- clientId = randomUUID();
8
- releaseId;
9
- constructor(releaseId) {
10
- super();
11
- if (releaseId !== undefined)
12
- this.releaseId = releaseId;
13
- }
14
- #socket = null;
15
- #pending = new Map();
16
- async connect(endpoint, timeoutMs = 5_000) {
17
- if (this.#socket)
18
- throw new Error("client is already connected");
19
- const deadline = Date.now() + timeoutMs;
20
- let lastError = null;
21
- while (Date.now() < deadline) {
22
- try {
23
- return await this.#connectOnce(endpoint, Math.max(1, deadline - Date.now()));
24
- }
25
- catch (error) {
26
- lastError = error instanceof Error ? error : new Error(String(error));
27
- if (!isTransientEndpointError(lastError))
28
- throw lastError;
29
- await new Promise(resolve => setTimeout(resolve, Math.min(40, Math.max(1, deadline - Date.now()))));
30
- }
31
- }
32
- throw new Error(`supervisor endpoint ${endpoint} remained unavailable for ${timeoutMs}ms`, { cause: lastError ?? undefined });
33
- }
34
- #connectOnce(endpoint, timeoutMs) {
35
- const socket = connect(endpoint);
36
- this.#socket = socket;
37
- socket.setNoDelay(true);
38
- const decoder = new LineFrameDecoder();
39
- return new Promise((resolve, reject) => {
40
- let welcomed = false;
41
- const timeout = setTimeout(() => {
42
- const error = transientError(`supervisor connection timed out after ${timeoutMs}ms`, "ETIMEDOUT");
43
- fail(error);
44
- socket.destroy();
45
- }, timeoutMs);
46
- const fail = (error) => {
47
- clearTimeout(timeout);
48
- if (!welcomed)
49
- reject(error);
50
- };
51
- socket.once("error", fail);
52
- socket.on("close", () => {
53
- if (this.#socket === socket)
54
- this.#socket = null;
55
- if (!welcomed) {
56
- fail(transientError("supervisor disconnected before completing its handshake", "ECONNRESET"));
57
- return;
58
- }
59
- for (const pending of this.#pending.values())
60
- pending.reject(new Error("supervisor disconnected"));
61
- this.#pending.clear();
62
- this.emit("disconnect");
63
- });
64
- socket.on("data", chunk => {
65
- try {
66
- for (const value of decoder.push(chunk)) {
67
- const message = value;
68
- if (message.type === "server-hello" && message.snapshot) {
69
- const hello = message;
70
- if (hello.envelope !== CONTROL_ENVELOPE || hello.envelopeRevision !== CONTROL_ENVELOPE_REVISION || !Array.isArray(hello.requiredFeatures) || !Array.isArray(hello.optionalFeatures) || typeof hello.contractDigest !== "string") {
71
- fail(new Error("supervisor returned an invalid control handshake"));
72
- socket.destroy();
73
- continue;
74
- }
75
- const negotiation = negotiateControlFeatures(localControlHello(this.releaseId), hello);
76
- if (!negotiation.ok) {
77
- fail(new Error(negotiation.diagnostic));
78
- socket.destroy();
79
- continue;
80
- }
81
- welcomed = true;
82
- clearTimeout(timeout);
83
- resolve(message.snapshot);
84
- }
85
- else if (message.type === "snapshot" && message.snapshot) {
86
- this.emit("snapshot", message.snapshot);
87
- }
88
- else if (message.type === "command-result" && message.result) {
89
- const pending = this.#pending.get(message.result.requestId);
90
- if (pending) {
91
- this.#pending.delete(message.result.requestId);
92
- pending.resolve(message.result);
93
- }
94
- }
95
- else if (message.type === "stop-launch-instance" && message.instanceId && message.requestId && message.reason) {
96
- this.emit("stopIntent", message);
97
- }
98
- else if (message.type === "protocol-error") {
99
- fail(new Error(message.message ?? "protocol error"));
100
- }
101
- }
102
- }
103
- catch (error) {
104
- fail(error instanceof Error ? error : new Error(String(error)));
105
- socket.destroy();
106
- }
107
- });
108
- socket.once("connect", () => socket.write(encodeFrame({ type: "client-hello", clientId: this.clientId, ...localControlHello(this.releaseId) })));
109
- });
110
- }
111
- command(command) {
112
- if (!this.#socket)
113
- return Promise.reject(new Error("supervisor is not connected"));
114
- return new Promise((resolve, reject) => {
115
- this.#pending.set(command.requestId, { resolve, reject });
116
- this.#socket?.write(encodeFrame({ type: "command", command }));
117
- });
118
- }
119
- close() {
120
- this.#socket?.end();
121
- this.#socket = null;
122
- }
123
- }
124
- function isTransientEndpointError(error) {
125
- const code = "code" in error ? String(error.code) : "";
126
- return ["ENOENT", "ECONNREFUSED", "ECONNRESET", "EPIPE", "ETIMEDOUT"].includes(code);
127
- }
128
- function transientError(message, code) {
129
- return Object.assign(new Error(message), { code });
130
- }
@@ -1,3 +0,0 @@
1
- export { SupervisorClient } from "./client.js";
2
- export { CONTROL_ENVELOPE, CONTROL_ENVELOPE_REVISION, GENERATED_CONTRACT_DIGEST, LineFrameDecoder, MAX_CONTROL_FRAME_BYTES, OPTIONAL_CONTROL_FEATURES, REQUIRED_CONTROL_FEATURES, encodeFrame, isCommandMessage, isControlHello, localControlHello, negotiateControlFeatures, } from "./messages.js";
3
- export type { ClientMessage, ControlFeature, ControlHello, ControlNegotiation, ServerMessage } from "./messages.js";
@@ -1,2 +0,0 @@
1
- export { SupervisorClient } from "./client.js";
2
- export { CONTROL_ENVELOPE, CONTROL_ENVELOPE_REVISION, GENERATED_CONTRACT_DIGEST, LineFrameDecoder, MAX_CONTROL_FRAME_BYTES, OPTIONAL_CONTROL_FEATURES, REQUIRED_CONTROL_FEATURES, encodeFrame, isCommandMessage, isControlHello, localControlHello, negotiateControlFeatures, } from "./messages.js";
@@ -1,90 +0,0 @@
1
- import type { CommandResult, LaunchInstanceStopIntent, SupervisorCommand, SupervisorSnapshot } from "../lifecycle/index.js";
2
- export declare const CONTROL_ENVELOPE: string;
3
- export declare const CONTROL_ENVELOPE_REVISION: 1;
4
- export declare const REQUIRED_CONTROL_FEATURES: readonly ["handshake.features.v1", "snapshot.revision.v1", "commands.request-identity.v1", "generation.lifecycle.v1", "launch.instance-lifecycle.v1"];
5
- export declare const OPTIONAL_CONTROL_FEATURES: readonly ["messages.unknown-additive-ignore.v1", "snapshot.resynchronize.v1"];
6
- export type ControlFeature = string;
7
- export declare const GENERATED_CONTRACT_DIGEST: string;
8
- export declare const MAX_CONTROL_FRAME_BYTES: number;
9
- export interface ControlHello {
10
- readonly envelope: typeof CONTROL_ENVELOPE;
11
- readonly envelopeRevision: typeof CONTROL_ENVELOPE_REVISION;
12
- readonly requiredFeatures: readonly ControlFeature[];
13
- readonly optionalFeatures: readonly ControlFeature[];
14
- readonly contractDigest: string;
15
- readonly releaseId?: string;
16
- }
17
- export type ClientMessage = {
18
- readonly type: "identity-probe";
19
- } | {
20
- readonly type: "release-idle-ownership";
21
- readonly bootNonce: string;
22
- readonly candidateReleaseId: string;
23
- } | {
24
- readonly type: "release-update-ownership";
25
- readonly bootNonce: string;
26
- readonly targetVersion: string;
27
- } | ({
28
- readonly type: "client-hello";
29
- readonly clientId: string;
30
- } & ControlHello) | {
31
- readonly type: "command";
32
- readonly command: SupervisorCommand;
33
- };
34
- export type ServerMessage = {
35
- readonly type: "identity";
36
- readonly supervisorId: string;
37
- readonly bootNonce: string;
38
- readonly pidStartIdentity: string;
39
- readonly releaseId: string;
40
- } | {
41
- readonly type: "release-ownership-result";
42
- readonly released: boolean;
43
- readonly reason: string;
44
- readonly liveInstanceIds: readonly string[];
45
- } | {
46
- readonly type: "release-update-result";
47
- readonly accepted: boolean;
48
- readonly reason: string;
49
- readonly liveInstanceIds: readonly string[];
50
- } | ({
51
- readonly type: "server-hello";
52
- readonly supervisorId: string;
53
- readonly bootNonce: string;
54
- readonly pidStartIdentity: string;
55
- readonly negotiatedFeatures: readonly string[];
56
- readonly snapshot: SupervisorSnapshot;
57
- } & ControlHello) | {
58
- readonly type: "snapshot";
59
- readonly snapshot: SupervisorSnapshot;
60
- } | {
61
- readonly type: "command-result";
62
- readonly result: CommandResult;
63
- } | LaunchInstanceStopIntent | {
64
- readonly type: "protocol-error";
65
- readonly code: string;
66
- readonly message: string;
67
- readonly diagnostics?: unknown;
68
- };
69
- export interface ControlNegotiation {
70
- readonly ok: boolean;
71
- readonly negotiatedFeatures: readonly string[];
72
- readonly missingFromClient: readonly string[];
73
- readonly missingFromServer: readonly string[];
74
- readonly diagnostic: string;
75
- }
76
- export declare function localControlHello(releaseId?: string): ControlHello;
77
- export declare function negotiateControlFeatures(client: ControlHello, server?: ControlHello): ControlNegotiation;
78
- export declare function encodeFrame(message: ClientMessage | ServerMessage | Readonly<Record<string, unknown>>): string;
79
- /** Incrementally decodes size-bounded newline-delimited control frames from arbitrary chunks. */
80
- export declare class LineFrameDecoder {
81
- #private;
82
- push(chunk: Buffer | string): unknown[];
83
- }
84
- export declare function isControlHello(value: unknown): value is {
85
- readonly type: "client-hello";
86
- readonly clientId: string;
87
- } & ControlHello;
88
- export declare function isCommandMessage(value: unknown): value is Extract<ClientMessage, {
89
- type: "command";
90
- }>;
@@ -1,100 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import { PRODUCT_IDENTITY } from "../../product-identity.js";
3
- export const CONTROL_ENVELOPE = PRODUCT_IDENTITY.protocol.controlEnvelope;
4
- export const CONTROL_ENVELOPE_REVISION = 1;
5
- export const REQUIRED_CONTROL_FEATURES = [
6
- "handshake.features.v1",
7
- "snapshot.revision.v1",
8
- "commands.request-identity.v1",
9
- "generation.lifecycle.v1",
10
- "launch.instance-lifecycle.v1",
11
- ];
12
- export const OPTIONAL_CONTROL_FEATURES = [
13
- "messages.unknown-additive-ignore.v1",
14
- "snapshot.resynchronize.v1",
15
- ];
16
- export const GENERATED_CONTRACT_DIGEST = createHash("sha256").update(JSON.stringify({
17
- envelope: CONTROL_ENVELOPE,
18
- revision: CONTROL_ENVELOPE_REVISION,
19
- required: [...REQUIRED_CONTROL_FEATURES].sort(),
20
- optional: [...OPTIONAL_CONTROL_FEATURES].sort(),
21
- })).digest("hex");
22
- export const MAX_CONTROL_FRAME_BYTES = 4 * 1024 * 1024;
23
- export function localControlHello(releaseId) {
24
- return {
25
- envelope: CONTROL_ENVELOPE,
26
- envelopeRevision: CONTROL_ENVELOPE_REVISION,
27
- requiredFeatures: REQUIRED_CONTROL_FEATURES,
28
- optionalFeatures: OPTIONAL_CONTROL_FEATURES,
29
- contractDigest: GENERATED_CONTRACT_DIGEST,
30
- ...(releaseId ? { releaseId } : {}),
31
- };
32
- }
33
- export function negotiateControlFeatures(client, server = localControlHello()) {
34
- if (client.envelope !== server.envelope || client.envelopeRevision !== server.envelopeRevision) {
35
- return {
36
- ok: false,
37
- negotiatedFeatures: [],
38
- missingFromClient: [],
39
- missingFromServer: [],
40
- diagnostic: `control envelope mismatch: client ${client.envelope}/${client.envelopeRevision}; server ${server.envelope}/${server.envelopeRevision}`,
41
- };
42
- }
43
- const clientFeatures = new Set([...client.requiredFeatures, ...client.optionalFeatures]);
44
- const serverFeatures = new Set([...server.requiredFeatures, ...server.optionalFeatures]);
45
- const missingFromClient = server.requiredFeatures.filter(feature => !clientFeatures.has(feature));
46
- const missingFromServer = client.requiredFeatures.filter(feature => !serverFeatures.has(feature));
47
- const negotiatedFeatures = [...clientFeatures].filter(feature => serverFeatures.has(feature)).sort();
48
- return {
49
- ok: missingFromClient.length === 0 && missingFromServer.length === 0,
50
- negotiatedFeatures,
51
- missingFromClient,
52
- missingFromServer,
53
- diagnostic: missingFromClient.length === 0 && missingFromServer.length === 0
54
- ? `control features negotiated (${negotiatedFeatures.join(", ")}); contract client=${client.contractDigest} server=${server.contractDigest}`
55
- : `required control features unavailable; client missing [${missingFromClient.join(", ")}], server missing [${missingFromServer.join(", ")}]; contract client=${client.contractDigest} server=${server.contractDigest}`,
56
- };
57
- }
58
- export function encodeFrame(message) {
59
- return `${JSON.stringify(message)}\n`;
60
- }
61
- /** Incrementally decodes size-bounded newline-delimited control frames from arbitrary chunks. */
62
- export class LineFrameDecoder {
63
- #buffer = "";
64
- push(chunk) {
65
- this.#buffer += typeof chunk === "string" ? chunk : chunk.toString("utf8");
66
- if (Buffer.byteLength(this.#buffer, "utf8") > MAX_CONTROL_FRAME_BYTES) {
67
- this.#buffer = "";
68
- throw new Error("control frame exceeds maximum size");
69
- }
70
- const messages = [];
71
- let newline = this.#buffer.indexOf("\n");
72
- while (newline >= 0) {
73
- const line = this.#buffer.slice(0, newline);
74
- this.#buffer = this.#buffer.slice(newline + 1);
75
- if (line.length > 0)
76
- messages.push(JSON.parse(line));
77
- newline = this.#buffer.indexOf("\n");
78
- }
79
- return messages;
80
- }
81
- }
82
- export function isControlHello(value) {
83
- if (!isRecord(value) || value.type !== "client-hello" || typeof value.clientId !== "string")
84
- return false;
85
- return value.envelope === CONTROL_ENVELOPE
86
- && value.envelopeRevision === CONTROL_ENVELOPE_REVISION
87
- && isStringArray(value.requiredFeatures)
88
- && isStringArray(value.optionalFeatures)
89
- && typeof value.contractDigest === "string"
90
- && (value.releaseId === undefined || typeof value.releaseId === "string");
91
- }
92
- export function isCommandMessage(value) {
93
- return isRecord(value) && value.type === "command" && isRecord(value.command) && typeof value.command.type === "string";
94
- }
95
- function isRecord(value) {
96
- return typeof value === "object" && value !== null;
97
- }
98
- function isStringArray(value) {
99
- return Array.isArray(value) && value.every(item => typeof item === "string" && item.length > 0);
100
- }
@@ -1,33 +0,0 @@
1
- import type { CohortState, SupervisorEndpointMetadata } from "./cohort-state.js";
2
- import type { MaterializedRelease } from "./release-store.js";
3
- export type OwnershipProbe = "live-verified" | "dead" | "unresponsive" | "identity-mismatch";
4
- export type CohortLaunchDecision = {
5
- readonly action: "launch-retained-ui";
6
- readonly releaseId: string;
7
- readonly releaseRoot: string;
8
- readonly reason: string;
9
- readonly recordPending: boolean;
10
- } | {
11
- readonly action: "activate-candidate";
12
- readonly releaseId: string;
13
- readonly releaseRoot: string;
14
- readonly reason: string;
15
- } | {
16
- readonly action: "replace-idle-cohort";
17
- readonly releaseId: string;
18
- readonly releaseRoot: string;
19
- readonly reason: string;
20
- readonly pid: number;
21
- } | {
22
- readonly action: "start-active";
23
- readonly releaseId: string;
24
- readonly releaseRoot: string;
25
- readonly reason: string;
26
- } | {
27
- readonly action: "blocked";
28
- readonly releaseId: string;
29
- readonly releaseRoot: string;
30
- readonly reason: string;
31
- readonly pid: number | null;
32
- };
33
- export declare function selectCohortLaunch(candidate: MaterializedRelease, state: CohortState, endpoint: SupervisorEndpointMetadata | null, probe: OwnershipProbe): CohortLaunchDecision;
@@ -1,67 +0,0 @@
1
- export function selectCohortLaunch(candidate, state, endpoint, probe) {
2
- if (endpoint && probe === "live-verified") {
3
- const retained = state.releases[endpoint.releaseId];
4
- if (!retained || retained.releaseRoot !== endpoint.releaseRoot || retained.contentDigest !== endpoint.contentDigest) {
5
- return {
6
- action: "blocked",
7
- releaseId: endpoint.releaseId,
8
- releaseRoot: endpoint.releaseRoot,
9
- reason: "live supervisor identity does not match a retained verified release record",
10
- pid: endpoint.pid,
11
- };
12
- }
13
- if (endpoint.releaseId !== candidate.releaseId && endpoint.ownership.liveInstanceIds.length === 0) {
14
- return {
15
- action: "replace-idle-cohort",
16
- releaseId: candidate.releaseId,
17
- releaseRoot: candidate.releaseRoot,
18
- reason: "older cohort is idle and can release ownership for verified candidate activation",
19
- pid: endpoint.pid,
20
- };
21
- }
22
- return {
23
- action: "launch-retained-ui",
24
- releaseId: endpoint.releaseId,
25
- releaseRoot: endpoint.releaseRoot,
26
- reason: endpoint.releaseId === candidate.releaseId
27
- ? "live supervisor already owns the installed release cohort"
28
- : "live supervisor owns a non-resumable generation; candidate remains pending",
29
- recordPending: endpoint.releaseId !== candidate.releaseId,
30
- };
31
- }
32
- if (endpoint && probe === "unresponsive") {
33
- // Security: even an empty persisted list cannot authorize killing an unresponsive process.
34
- return {
35
- action: "blocked",
36
- releaseId: endpoint.releaseId,
37
- releaseRoot: endpoint.releaseRoot,
38
- reason: "the background service did not respond after automatic recovery; retry shortly",
39
- pid: endpoint.pid,
40
- };
41
- }
42
- if (endpoint && probe === "identity-mismatch") {
43
- return {
44
- action: "blocked",
45
- releaseId: endpoint.releaseId,
46
- releaseRoot: endpoint.releaseRoot,
47
- reason: "endpoint handshake, boot nonce, or process start identity did not match durable ownership metadata",
48
- pid: endpoint.pid,
49
- };
50
- }
51
- const active = state.references.active ? state.releases[state.references.active] : undefined;
52
- const approvedCandidate = state.releases[candidate.releaseId]?.approval === "approved";
53
- if (approvedCandidate || !active) {
54
- return {
55
- action: "activate-candidate",
56
- releaseId: candidate.releaseId,
57
- releaseRoot: candidate.releaseRoot,
58
- reason: approvedCandidate ? "approved candidate can become the active cohort" : "initial verified release can be certified and activated",
59
- };
60
- }
61
- return {
62
- action: "start-active",
63
- releaseId: active.releaseId,
64
- releaseRoot: active.releaseRoot,
65
- reason: "candidate is not approved; retaining the active release",
66
- };
67
- }
@@ -1,2 +0,0 @@
1
- /** Serialize endpoint publication and retirement using a lock released by the OS on process death. */
2
- export declare function withEndpointLock<T>(metadataPath: string, operation: () => Promise<T>): Promise<T>;
@@ -1,37 +0,0 @@
1
- import { mkdir, realpath } from "node:fs/promises";
2
- import { basename, dirname, join } from "node:path";
3
- import { setTimeout as delay } from "node:timers/promises";
4
- import { acquireSupervisorGate } from "./supervisor-identity.js";
5
- /** Serialize endpoint publication and retirement using a lock released by the OS on process death. */
6
- export async function withEndpointLock(metadataPath, operation) {
7
- let authority;
8
- try {
9
- await mkdir(dirname(metadataPath), { recursive: true, mode: 0o700 });
10
- authority = join(await realpath(dirname(metadataPath)), `${basename(metadataPath)}.authority`);
11
- }
12
- catch (cause) {
13
- throw Object.assign(new Error("cannot access A1 startup state; check runtime-directory permissions and free disk space", { cause }), { code: "SUPERVISOR_RECOVERY_UNAVAILABLE" });
14
- }
15
- const deadline = Date.now() + 3_000;
16
- for (;;) {
17
- let gate;
18
- try {
19
- gate = acquireSupervisorGate(authority);
20
- }
21
- catch (cause) {
22
- throw Object.assign(new Error("cannot access A1 startup coordination; check installation and runtime-directory permissions", { cause }), { code: "SUPERVISOR_RECOVERY_UNAVAILABLE" });
23
- }
24
- if (gate.acquired) {
25
- try {
26
- return await operation();
27
- }
28
- finally {
29
- gate.release();
30
- }
31
- }
32
- gate.release();
33
- if (Date.now() >= deadline)
34
- throw Object.assign(new Error("another A1 startup is still preparing; retry shortly"), { code: "SUPERVISOR_RECOVERY_BUSY" });
35
- await delay(20);
36
- }
37
- }
@@ -1,10 +0,0 @@
1
- import type { SupervisorEndpointMetadata } from "./cohort-state.js";
2
- interface SupervisorRecoveryOptions {
3
- readonly metadataPath: string;
4
- readonly endpoint: string;
5
- readonly matches: (metadata: SupervisorEndpointMetadata) => boolean;
6
- readonly startAndWait: () => Promise<void>;
7
- }
8
- /** Recover all launch routes identically; a retry never grants permission to kill a live process. */
9
- export declare function recoverSupervisorEndpoint(options: SupervisorRecoveryOptions): Promise<void>;
10
- export {};
@@ -1,45 +0,0 @@
1
- import { writeFile } from "node:fs/promises";
2
- import { probeOwnership, readEndpointMetadata, removeEndpointArtifacts } from "./endpoints.js";
3
- /** Recover all launch routes identically; a retry never grants permission to kill a live process. */
4
- export async function recoverSupervisorEndpoint(options) {
5
- const { metadataPath, endpoint } = options;
6
- let recovered = false;
7
- for (let attempt = 0; attempt < 3; attempt++) {
8
- const metadata = await readEndpointMetadata(metadataPath);
9
- if (metadata) {
10
- const probe = await probeOwnership(metadata);
11
- if (probe === "live-verified" && options.matches(metadata)) {
12
- if (recovered)
13
- await diagnostic(metadataPath, "recovered", attempt + 1);
14
- return;
15
- }
16
- // Concurrency: another owner may have published while an earlier identity probe was pending.
17
- if (JSON.stringify(await readEndpointMetadata(metadataPath)) !== JSON.stringify(metadata))
18
- continue;
19
- if (probe !== "dead") {
20
- await diagnostic(metadataPath, probe, attempt + 1);
21
- throw Object.assign(new Error(probe === "unresponsive"
22
- ? "A1's background service is not responding; retry shortly. Your sessions have been preserved."
23
- : "A1's background service identity changed; retry startup. Your sessions have been preserved."), {
24
- code: "SUPERVISOR_RECOVERY_BLOCKED",
25
- });
26
- }
27
- recovered = true;
28
- if (!await removeEndpointArtifacts(metadataPath, endpoint, metadata))
29
- continue;
30
- await diagnostic(metadataPath, "stale-owner-retired", attempt + 1);
31
- }
32
- // Concurrency: the child takes the same endpoint gate before binding/publication. If another launch wins,
33
- // startAndWait joins its authenticated endpoint; it never unlinks that winner's socket.
34
- await options.startAndWait();
35
- if (recovered)
36
- await diagnostic(metadataPath, "recovered", attempt + 1);
37
- return;
38
- }
39
- await diagnostic(metadataPath, "ownership-changing", 3);
40
- throw Object.assign(new Error("A1 startup changed repeatedly; retry shortly"), { code: "SUPERVISOR_RECOVERY_BUSY" });
41
- }
42
- async function diagnostic(path, reason, attempts) {
43
- // Security: one bounded summary per endpoint, no raw metadata, user paths, or session content.
44
- await writeFile(`${path}.recovery.json`, JSON.stringify({ reason, attempts, at: new Date().toISOString() }), { mode: 0o600 }).catch(() => undefined);
45
- }
@@ -1,32 +0,0 @@
1
- import type { OwnershipProbe } from "./cohort-selection.js";
2
- import { type ObserveSupervisorProcess } from "./supervisor-identity.js";
3
- import type { SupervisorEndpointMetadata } from "./cohort-state.js";
4
- import type { CohortEndpointPaths, ProductPaths } from "../lifecycle/index.js";
5
- export interface RecordedEndpoint {
6
- readonly metadata: SupervisorEndpointMetadata;
7
- readonly paths: CohortEndpointPaths;
8
- }
9
- /**
10
- * Every endpoint recorded under this runtime directory: one per cohort, plus the single
11
- * endpoint published by releases that predate cohort-scoped identity. More than one can be
12
- * live at a time, and each is validated on its own identity rather than by being the only one.
13
- */
14
- export declare function listRecordedEndpoints(paths: ProductPaths): Promise<readonly RecordedEndpoint[]>;
15
- /**
16
- * Removes the records of cohorts whose processes are gone. A record left by a cohort that
17
- * exited without cleaning up is not evidence of ownership, and a later launch should not have
18
- * to reason about it. Returns the release ids whose records were removed.
19
- */
20
- export declare function sweepDeadEndpoints(paths: ProductPaths): Promise<readonly string[]>;
21
- /** The releases that an identity-verified live cohort runs from and that must be retained. */
22
- export declare function liveReleaseIds(paths: ProductPaths): Promise<readonly string[]>;
23
- export declare function readEndpointMetadata(path: string): Promise<SupervisorEndpointMetadata | null>;
24
- export interface OwnershipProbeOptions {
25
- readonly observe?: ObserveSupervisorProcess;
26
- readonly attempts?: number;
27
- readonly timeoutMs?: number;
28
- }
29
- /** Reprobe transient failures; only native absence or a replaced generation establishes death. */
30
- export declare function probeOwnership(metadata: SupervisorEndpointMetadata, options?: OwnershipProbeOptions): Promise<OwnershipProbe>;
31
- /** Retire only a still-dead exact publication. Socket removal belongs to the gated listener. */
32
- export declare function removeEndpointArtifacts(metadataPath: string, endpoint: string, expected: SupervisorEndpointMetadata): Promise<boolean>;