@timurproko/a1 0.1.8-dev.3b54f21 → 0.1.8-dev.402

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 (642) hide show
  1. package/README.md +159 -65
  2. package/bin/cli.js +28 -10
  3. package/bin/guardian.js +12 -6
  4. package/bin/module-identity.js +69 -35
  5. package/bin/pi-tui.d.ts +6 -0
  6. package/bin/pi-tui.js +28 -0
  7. package/bin/release-cleanup.js +8 -0
  8. package/bin/supervisor.js +2 -2
  9. package/bin/sync-pi-tui-proxy.js +97 -0
  10. package/bin/ui.js +62 -21
  11. package/bin/update-recovery.js +274 -0
  12. package/bin/warmup.js +27 -0
  13. package/dist/cli/capabilities.d.ts +6 -0
  14. package/dist/{src/cli → cli}/capabilities.js +1 -1
  15. package/dist/{src/cli → cli}/dispatch.d.ts +15 -1
  16. package/dist/cli/dispatch.js +261 -0
  17. package/dist/cli/package-messages.d.ts +26 -0
  18. package/dist/cli/package-messages.js +71 -0
  19. package/dist/{src/cli → cli}/packages.d.ts +11 -2
  20. package/dist/{src/cli → cli}/packages.js +24 -27
  21. package/dist/{src/cli → cli}/version-stats.d.ts +6 -0
  22. package/dist/cli/version-stats.js +112 -0
  23. package/dist/composition/agent-engine-bridge.d.ts +3 -0
  24. package/dist/composition/agent-engine-bridge.js +108 -0
  25. package/dist/composition/index.d.ts +3 -0
  26. package/dist/composition/index.js +3 -0
  27. package/dist/composition/owned-ui.d.ts +35 -0
  28. package/dist/composition/owned-ui.js +118 -0
  29. package/dist/composition/process.d.ts +16 -0
  30. package/dist/composition/process.js +45 -0
  31. package/dist/composition/settings-route-host.d.ts +8 -0
  32. package/dist/composition/settings-route-host.js +75 -0
  33. package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/capability-ports.d.ts +2 -2
  34. package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/domain-validation.js +22 -4
  35. package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/domain.d.ts +17 -0
  36. package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/package-ports.d.ts +6 -0
  37. package/dist/contracts/owned-ui/image-attachments.d.ts +36 -0
  38. package/dist/contracts/owned-ui/image-attachments.js +67 -0
  39. package/dist/contracts/owned-ui/index.d.ts +8 -0
  40. package/dist/contracts/owned-ui/index.js +8 -0
  41. package/dist/{src/foundation/owned-ui-contracts → contracts/owned-ui}/model.d.ts +123 -0
  42. package/dist/contracts/owned-ui/prompt-history.d.ts +55 -0
  43. package/dist/contracts/owned-ui/prompt-history.js +23 -0
  44. package/dist/contracts/owned-ui/prompt-suggestions.d.ts +3 -0
  45. package/dist/contracts/owned-ui/prompt-suggestions.js +44 -0
  46. package/dist/contracts/owned-ui/suggestion-diagnostics.d.ts +22 -0
  47. package/dist/contracts/owned-ui/suggestion-diagnostics.js +9 -0
  48. package/dist/contracts/owned-ui/transcript-lifecycle.d.ts +5 -0
  49. package/dist/contracts/owned-ui/transcript-lifecycle.js +33 -0
  50. package/dist/{src/foundation/owned-ui-contracts → contracts/owned-ui}/validation.d.ts +5 -1
  51. package/dist/{src/foundation/owned-ui-contracts → contracts/owned-ui}/validation.js +129 -4
  52. package/dist/{src/foundation/presentation-contracts → contracts/presentation}/index.d.ts +8 -0
  53. package/dist/{src/features → features}/launch/development-launch.js +11 -3
  54. package/dist/{src/features → features}/launch/index.d.ts +0 -1
  55. package/dist/{src/features → features}/launch/index.js +0 -1
  56. package/dist/features/launch/intent.d.ts +10 -0
  57. package/dist/features/launch/intent.js +8 -0
  58. package/dist/{src/features → features}/launch/prepare-launch.d.ts +0 -2
  59. package/dist/{src/features → features}/launch/prepare-launch.js +2 -9
  60. package/dist/{src/features → features}/launch/profile-paths.d.ts +3 -2
  61. package/dist/{src/features → features}/launch/profile-paths.js +13 -8
  62. package/dist/{src/features → features}/launch/runtime-selection.d.ts +2 -5
  63. package/dist/{src/features → features}/owned-ui/customization.d.ts +3 -1
  64. package/dist/{src/features → features}/owned-ui/customization.js +3 -1
  65. package/dist/{src/features → features}/owned-ui/diagnostics.d.ts +2 -1
  66. package/dist/{src/features → features}/owned-ui/diagnostics.js +1 -0
  67. package/dist/{src/features → features}/owned-ui/index.d.ts +2 -0
  68. package/dist/{src/features → features}/owned-ui/index.js +2 -0
  69. package/dist/features/owned-ui/project-trust-prompt.d.ts +25 -0
  70. package/dist/features/owned-ui/project-trust-prompt.js +149 -0
  71. package/dist/{src/features → features}/owned-ui/run.d.ts +2 -2
  72. package/dist/features/owned-ui/run.js +32 -0
  73. package/dist/features/owned-ui/session-fork-prompt.d.ts +8 -0
  74. package/dist/features/owned-ui/session-fork-prompt.js +34 -0
  75. package/dist/{src/features → features}/owned-ui/settings-app.d.ts +3 -3
  76. package/dist/{src/features → features}/owned-ui/settings-app.js +105 -56
  77. package/dist/features/prompt-history/image-sidecar.d.ts +32 -0
  78. package/dist/features/prompt-history/image-sidecar.js +130 -0
  79. package/dist/features/prompt-history/index.d.ts +4 -0
  80. package/dist/features/prompt-history/index.js +3 -0
  81. package/dist/features/prompt-history/paths.d.ts +5 -0
  82. package/dist/features/prompt-history/paths.js +17 -0
  83. package/dist/features/prompt-history/service.d.ts +54 -0
  84. package/dist/features/prompt-history/service.js +425 -0
  85. package/dist/features/prompt-history/store.d.ts +16 -0
  86. package/dist/features/prompt-history/store.js +223 -0
  87. package/dist/features/prompt-history/worker.d.ts +9 -0
  88. package/dist/features/prompt-history/worker.js +45 -0
  89. package/dist/features/prompt-suggestions/diagnostics.d.ts +18 -0
  90. package/dist/features/prompt-suggestions/diagnostics.js +82 -0
  91. package/dist/features/prompt-suggestions/index.d.ts +1 -0
  92. package/dist/features/prompt-suggestions/index.js +1 -0
  93. package/dist/{src/features → features}/workspace/capabilities.d.ts +1 -1
  94. package/dist/{src/features → features}/workspace/reducer.d.ts +2 -1
  95. package/dist/{src/features → features}/workspace/reducer.js +2 -1
  96. package/dist/{src/features → features}/workspace/router.d.ts +2 -1
  97. package/dist/{src/features → features}/workspace/router.js +1 -0
  98. package/dist/{src/features → features}/workspace/store.d.ts +2 -1
  99. package/dist/{src/features → features}/workspace/store.js +1 -0
  100. package/dist/foundation/launch-context/index.d.ts +59 -0
  101. package/dist/foundation/launch-context/index.js +136 -0
  102. package/dist/{src/foundation → foundation}/launch-guardian/main.d.ts +2 -0
  103. package/dist/{src/foundation → foundation}/launch-guardian/main.js +23 -8
  104. package/dist/{src/foundation → foundation}/lifecycle/index.d.ts +2 -0
  105. package/dist/{src/foundation → foundation}/lifecycle/index.js +2 -0
  106. package/dist/{src/foundation → foundation}/lifecycle/model.d.ts +1 -1
  107. package/dist/{src/foundation → foundation}/lifecycle/model.js +1 -1
  108. package/dist/foundation/lifecycle/paths.d.ts +30 -0
  109. package/dist/{src/foundation → foundation}/lifecycle/paths.js +29 -1
  110. package/dist/foundation/lifecycle/session-selection.d.ts +9 -0
  111. package/dist/foundation/lifecycle/session-selection.js +39 -0
  112. package/dist/foundation/lifecycle/supervisor-startup.d.ts +30 -0
  113. package/dist/foundation/lifecycle/supervisor-startup.js +106 -0
  114. package/dist/{src/foundation → foundation}/native-host-protocol/codec.d.ts +2 -0
  115. package/dist/{src/foundation → foundation}/native-host-protocol/codec.js +2 -0
  116. package/dist/{src/foundation → foundation}/native-host-protocol/messages.d.ts +1 -1
  117. package/dist/{src/foundation → foundation}/native-host-protocol/messages.js +1 -1
  118. package/dist/foundation/process-containment/darwin-process-inspector.d.ts +5 -0
  119. package/dist/foundation/process-containment/darwin-process-inspector.js +7 -0
  120. package/dist/{src/foundation → foundation}/process-containment/index.d.ts +1 -0
  121. package/dist/{src/foundation → foundation}/process-containment/index.js +1 -0
  122. package/dist/{src/foundation → foundation}/process-containment/linux-process-inspector.d.ts +1 -0
  123. package/dist/{src/foundation → foundation}/process-containment/linux-process-inspector.js +1 -0
  124. package/dist/{src/foundation → foundation}/process-containment/native-guardian-containment.d.ts +1 -0
  125. package/dist/{src/foundation → foundation}/process-containment/native-guardian-containment.js +1 -0
  126. package/dist/{src/foundation → foundation}/process-containment/windows-process-inspector.d.ts +3 -1
  127. package/dist/{src/foundation → foundation}/process-containment/windows-process-inspector.js +5 -2
  128. package/dist/{src/foundation → foundation}/protocol/client.d.ts +1 -0
  129. package/dist/{src/foundation → foundation}/protocol/client.js +1 -0
  130. package/dist/{src/foundation → foundation}/protocol/messages.d.ts +1 -0
  131. package/dist/{src/foundation → foundation}/protocol/messages.js +1 -0
  132. package/dist/foundation/release/bootstrap.d.ts +55 -0
  133. package/dist/{src/foundation → foundation}/release/bootstrap.js +219 -46
  134. package/dist/foundation/release/cohort-state.d.ts +157 -0
  135. package/dist/foundation/release/cohort-state.js +472 -0
  136. package/dist/foundation/release/dependency-certification-retention.d.ts +7 -0
  137. package/dist/foundation/release/dependency-certification-retention.js +88 -0
  138. package/dist/foundation/release/dependency-certification.d.ts +24 -0
  139. package/dist/foundation/release/dependency-certification.js +266 -0
  140. package/dist/foundation/release/dependency-layer.d.ts +81 -0
  141. package/dist/foundation/release/dependency-layer.js +466 -0
  142. package/dist/foundation/release/endpoints.d.ts +20 -0
  143. package/dist/foundation/release/endpoints.js +50 -0
  144. package/dist/foundation/release/immutable-platform.d.ts +6 -0
  145. package/dist/foundation/release/immutable-platform.js +13 -0
  146. package/dist/{src/foundation → foundation}/release/index.d.ts +6 -0
  147. package/dist/{src/foundation → foundation}/release/index.js +6 -0
  148. package/dist/foundation/release/release-gc.d.ts +71 -0
  149. package/dist/foundation/release/release-gc.js +764 -0
  150. package/dist/{src/foundation → foundation}/release/release-store.d.ts +9 -3
  151. package/dist/{src/foundation → foundation}/release/release-store.js +74 -14
  152. package/dist/{src/foundation → foundation}/release/release.d.ts +6 -1
  153. package/dist/{src/foundation → foundation}/release/release.js +15 -4
  154. package/dist/foundation/release/restart-certification.d.ts +68 -0
  155. package/dist/foundation/release/restart-certification.js +227 -0
  156. package/dist/foundation/release/update-launch.d.ts +6 -0
  157. package/dist/foundation/release/update-launch.js +17 -0
  158. package/dist/foundation/release/update-recovery.d.ts +76 -0
  159. package/dist/foundation/release/update-recovery.js +356 -0
  160. package/dist/{src/foundation → foundation}/release/update-transaction.d.ts +11 -0
  161. package/dist/{src/foundation → foundation}/release/update-transaction.js +13 -1
  162. package/dist/{src/foundation → foundation}/release/update.d.ts +40 -4
  163. package/dist/{src/foundation → foundation}/release/update.js +196 -78
  164. package/dist/foundation/release/warmup.d.ts +3 -0
  165. package/dist/foundation/release/warmup.js +47 -0
  166. package/dist/foundation/startup/index.d.ts +1 -0
  167. package/dist/foundation/startup/index.js +1 -0
  168. package/dist/foundation/startup/startup-runtime.d.ts +36 -0
  169. package/dist/foundation/startup/startup-runtime.js +142 -0
  170. package/dist/{src/foundation → foundation}/storage/control-store.d.ts +2 -1
  171. package/dist/{src/foundation → foundation}/storage/control-store.js +39 -4
  172. package/dist/{src/foundation → foundation}/structured-agent-runtime/backpressure.d.ts +2 -1
  173. package/dist/{src/foundation → foundation}/structured-agent-runtime/backpressure.js +2 -1
  174. package/dist/{src/foundation → foundation}/structured-agent-runtime/commands.d.ts +2 -1
  175. package/dist/{src/foundation → foundation}/structured-agent-runtime/commands.js +2 -1
  176. package/dist/{src/foundation → foundation}/structured-agent-runtime/handshake.d.ts +1 -1
  177. package/dist/{src/foundation → foundation}/structured-agent-runtime/handshake.js +1 -1
  178. package/dist/{src/foundation → foundation}/structured-agent-runtime/reconnection.d.ts +2 -1
  179. package/dist/{src/foundation → foundation}/structured-agent-runtime/reconnection.js +2 -1
  180. package/dist/{src/foundation → foundation}/structured-agent-runtime/state.d.ts +2 -1
  181. package/dist/{src/foundation → foundation}/structured-agent-runtime/state.js +2 -1
  182. package/dist/foundation/supervision/index.d.ts +3 -0
  183. package/dist/foundation/supervision/index.js +3 -0
  184. package/dist/foundation/supervision/main.d.ts +1 -0
  185. package/dist/foundation/supervision/main.js +84 -0
  186. package/dist/foundation/supervision/paths.d.ts +1 -0
  187. package/dist/foundation/supervision/paths.js +1 -0
  188. package/dist/foundation/supervision/server.d.ts +51 -0
  189. package/dist/{src/foundation → foundation}/supervision/server.js +142 -20
  190. package/dist/foundation/terminal-cleanup/fatal-exit.d.ts +12 -0
  191. package/dist/foundation/terminal-cleanup/fatal-exit.js +85 -0
  192. package/dist/foundation/terminal-cleanup/index.d.ts +2 -0
  193. package/dist/foundation/terminal-cleanup/index.js +2 -0
  194. package/dist/foundation/terminal-cleanup/terminal-reset.d.ts +4 -0
  195. package/dist/foundation/terminal-cleanup/terminal-reset.js +40 -0
  196. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/components.d.ts +1 -1
  197. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/conformance.d.ts +1 -0
  198. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/conformance.js +3 -2
  199. package/dist/integrations/pi/components/editor-interaction.d.ts +38 -0
  200. package/dist/integrations/pi/components/history-editor-loader.d.ts +5 -0
  201. package/dist/integrations/pi/components/history-editor-loader.js +5 -0
  202. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/index.d.ts +2 -1
  203. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/index.js +2 -1
  204. package/dist/integrations/pi/components/owned-editor-ux.d.ts +74 -0
  205. package/dist/integrations/pi/components/owned-editor-ux.js +1093 -0
  206. package/dist/integrations/pi/components/path-word-ranges.d.ts +2 -0
  207. package/dist/integrations/pi/components/path-word-ranges.js +37 -0
  208. package/dist/integrations/pi/components/prompt-input-port.d.ts +18 -0
  209. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-components.d.ts +1 -0
  210. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-components.js +1 -0
  211. package/dist/integrations/pi/components/shell-editor-autocomplete.js +297 -0
  212. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-extension-ui.d.ts +1 -1
  213. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-footer-status.d.ts +4 -4
  214. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-footer-status.js +58 -23
  215. package/dist/integrations/pi/components/shell-presenters-info.d.ts +43 -0
  216. package/dist/integrations/pi/components/shell-presenters-info.js +114 -0
  217. package/dist/integrations/pi/components/shell-presenters-transcript.d.ts +29 -0
  218. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-presenters-transcript.js +174 -170
  219. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-selectors-dialogs.d.ts +8 -4
  220. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-selectors-dialogs.js +10 -6
  221. package/dist/integrations/pi/components/shell-shared-facade.d.ts +213 -0
  222. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-shared-facade.js +5 -2
  223. package/dist/integrations/pi/components/submitted-prompt-adapter.d.ts +15 -0
  224. package/dist/integrations/pi/components/submitted-prompt-adapter.js +43 -0
  225. package/dist/integrations/pi/components/tool-image-presentation.d.ts +21 -0
  226. package/dist/integrations/pi/components/tool-image-presentation.js +86 -0
  227. package/dist/integrations/pi/components/tool-result-adapter.d.ts +6 -0
  228. package/dist/integrations/pi/components/tool-result-adapter.js +27 -0
  229. package/dist/integrations/pi/components/transcript-image-resolver.d.ts +7 -0
  230. package/dist/integrations/pi/components/transcript-image-resolver.js +19 -0
  231. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/adjacent/core/keybindings.d.ts +11 -2
  232. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/adjacent/core/keybindings.js +41 -3
  233. package/dist/integrations/pi/components/upstream/assets/earendil-image.json +12 -0
  234. package/dist/integrations/pi/components/upstream/components/earendil-announcement.js +42 -0
  235. package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +40 -0
  236. package/dist/integrations/pi/components/upstream/components/owned-editor.js +166 -0
  237. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/scoped-models-selector.d.ts +1 -1
  238. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/scoped-models-selector.js +3 -1
  239. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/session-footer.d.ts +3 -2
  240. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/session-footer.js +12 -7
  241. package/dist/integrations/pi/components/upstream/components/tool-execution.d.ts +61 -0
  242. package/dist/integrations/pi/components/upstream/components/tool-execution.js +344 -0
  243. package/dist/integrations/pi/components/upstream/history/editor-core.d.ts +280 -0
  244. package/dist/integrations/pi/components/upstream/history/editor-core.js +2062 -0
  245. package/dist/integrations/pi/components/upstream/history/kill-ring.d.ts +32 -0
  246. package/dist/integrations/pi/components/upstream/history/kill-ring.js +48 -0
  247. package/dist/integrations/pi/components/upstream/history/printable-key.d.ts +1 -0
  248. package/dist/integrations/pi/components/upstream/history/printable-key.js +40 -0
  249. package/dist/integrations/pi/components/upstream/history/text-helpers.d.ts +14 -0
  250. package/dist/integrations/pi/components/upstream/history/text-helpers.js +28 -0
  251. package/dist/integrations/pi/components/upstream/history/undo-stack.d.ts +22 -0
  252. package/dist/integrations/pi/components/upstream/history/undo-stack.js +36 -0
  253. package/dist/integrations/pi/components/upstream/history/word-navigation.d.ts +24 -0
  254. package/dist/integrations/pi/components/upstream/history/word-navigation.js +100 -0
  255. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/adapter.d.ts +74 -6
  256. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/adapter.js +1340 -228
  257. package/dist/integrations/pi/engine/changelog.d.ts +2 -0
  258. package/dist/integrations/pi/engine/changelog.js +63 -0
  259. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/conformance.d.ts +4 -2
  260. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/conformance.js +15 -5
  261. package/dist/integrations/pi/engine/http-dispatcher.d.ts +4 -0
  262. package/dist/integrations/pi/engine/http-dispatcher.js +25 -0
  263. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/index.d.ts +4 -0
  264. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/index.js +4 -0
  265. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/model-auth-integration.d.ts +2 -1
  266. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/model-auth-integration.js +1 -0
  267. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/package-integration.d.ts +1 -1
  268. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/package-integration.js +32 -26
  269. package/dist/integrations/pi/engine/pending-delivery.d.ts +30 -0
  270. package/dist/integrations/pi/engine/pending-delivery.js +158 -0
  271. package/dist/integrations/pi/engine/project-trust-preflight.d.ts +22 -0
  272. package/dist/integrations/pi/engine/project-trust-preflight.js +50 -0
  273. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/resource-extension-integration.d.ts +2 -1
  274. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/resource-extension-integration.js +1 -0
  275. package/dist/integrations/pi/engine/resources/changelog.json +12 -0
  276. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/runtime-integration.d.ts +19 -1
  277. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/runtime-integration.js +56 -5
  278. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/session-integration.d.ts +4 -2
  279. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/session-integration.js +19 -4
  280. package/dist/integrations/pi/engine/session-selection.d.ts +28 -0
  281. package/dist/integrations/pi/engine/session-selection.js +90 -0
  282. package/dist/integrations/pi/engine/settings-effects.d.ts +66 -0
  283. package/dist/integrations/pi/engine/settings-effects.js +249 -0
  284. package/dist/integrations/pi/engine/settings-integration.d.ts +43 -0
  285. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/settings-integration.js +102 -108
  286. package/dist/integrations/pi/engine/tool-rendering.d.ts +13 -0
  287. package/dist/integrations/pi/engine/tool-rendering.js +145 -0
  288. package/dist/integrations/pi/engine/transcript-image-assets.d.ts +11 -0
  289. package/dist/integrations/pi/engine/transcript-image-assets.js +86 -0
  290. package/dist/integrations/pi/engine/windows-filesystem-hygiene.d.ts +21 -0
  291. package/dist/integrations/pi/engine/windows-filesystem-hygiene.js +55 -0
  292. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/workflow-controllers.d.ts +3 -2
  293. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/workflow-controllers.js +1 -0
  294. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/workflows.d.ts +19 -2
  295. package/dist/integrations/pi/session-ui/clipboard-diagnostics.d.ts +16 -0
  296. package/dist/integrations/pi/session-ui/clipboard-diagnostics.js +65 -0
  297. package/dist/integrations/pi/session-ui/clipboard-image.d.ts +11 -0
  298. package/dist/integrations/pi/session-ui/clipboard-image.js +38 -0
  299. package/dist/integrations/pi/session-ui/editor-hyperlink-budget.d.ts +9 -0
  300. package/dist/integrations/pi/session-ui/editor-hyperlink-budget.js +23 -0
  301. package/dist/integrations/pi/session-ui/image-preparation-client.d.ts +20 -0
  302. package/dist/integrations/pi/session-ui/image-preparation-client.js +145 -0
  303. package/dist/integrations/pi/session-ui/image-preparation.d.ts +18 -0
  304. package/dist/integrations/pi/session-ui/image-preparation.js +126 -0
  305. package/dist/integrations/pi/session-ui/image-source.d.ts +13 -0
  306. package/dist/integrations/pi/session-ui/image-source.js +171 -0
  307. package/dist/integrations/pi/session-ui/image-worker.d.ts +17 -0
  308. package/dist/integrations/pi/session-ui/image-worker.js +23 -0
  309. package/dist/integrations/pi/session-ui/index.d.ts +5 -0
  310. package/dist/integrations/pi/session-ui/index.js +5 -0
  311. package/dist/integrations/pi/session-ui/paste-executor.d.ts +10 -0
  312. package/dist/integrations/pi/session-ui/paste-executor.js +232 -0
  313. package/dist/integrations/pi/session-ui/paste-helper.d.ts +1 -0
  314. package/dist/integrations/pi/session-ui/paste-helper.js +173 -0
  315. package/dist/integrations/pi/session-ui/paste-preparation-client.d.ts +16 -0
  316. package/dist/integrations/pi/session-ui/paste-preparation-client.js +159 -0
  317. package/dist/integrations/pi/session-ui/paste-protocol.d.ts +78 -0
  318. package/dist/integrations/pi/session-ui/paste-protocol.js +18 -0
  319. package/dist/integrations/pi/session-ui/paste-text-preparation.d.ts +20 -0
  320. package/dist/integrations/pi/session-ui/paste-text-preparation.js +134 -0
  321. package/dist/integrations/pi/session-ui/paste-text-worker.d.ts +1 -0
  322. package/dist/integrations/pi/session-ui/paste-text-worker.js +12 -0
  323. package/dist/integrations/pi/session-ui/path-chip-presentation.d.ts +7 -0
  324. package/dist/integrations/pi/session-ui/path-chip-presentation.js +24 -0
  325. package/dist/integrations/pi/session-ui/prompt-chips.d.ts +72 -0
  326. package/dist/integrations/pi/session-ui/prompt-chips.js +503 -0
  327. package/dist/integrations/pi/session-ui/prompt-history-controller.d.ts +36 -0
  328. package/dist/integrations/pi/session-ui/prompt-history-controller.js +170 -0
  329. package/dist/integrations/pi/session-ui/prompt-suggestion-controller.d.ts +35 -0
  330. package/dist/integrations/pi/session-ui/prompt-suggestion-controller.js +207 -0
  331. package/dist/integrations/pi/session-ui/response-copy-coordinator.d.ts +27 -0
  332. package/dist/integrations/pi/session-ui/response-copy-coordinator.js +189 -0
  333. package/dist/integrations/pi/session-ui/response-copy-helper.d.ts +1 -0
  334. package/dist/integrations/pi/session-ui/response-copy-helper.js +122 -0
  335. package/dist/integrations/pi/session-ui/response-copy-protocol.d.ts +56 -0
  336. package/dist/integrations/pi/session-ui/response-copy-protocol.js +5 -0
  337. package/dist/integrations/pi/session-ui/response-copy-transport.d.ts +31 -0
  338. package/dist/integrations/pi/session-ui/response-copy-transport.js +187 -0
  339. package/dist/integrations/pi/session-ui/route-host.d.ts +5 -0
  340. package/dist/integrations/pi/session-ui/route-host.js +1 -0
  341. package/dist/integrations/pi/session-ui/session-shell-root.d.ts +221 -0
  342. package/dist/integrations/pi/session-ui/session-shell-root.js +1305 -0
  343. package/dist/integrations/pi/session-ui/session-shell.d.ts +55 -0
  344. package/dist/integrations/pi/session-ui/session-shell.js +1792 -0
  345. package/dist/integrations/pi/session-ui/session-viewport-controller.d.ts +56 -0
  346. package/dist/integrations/pi/session-ui/session-viewport-controller.js +569 -0
  347. package/dist/integrations/pi/session-ui/stream-presentation-coalescer.d.ts +29 -0
  348. package/dist/integrations/pi/session-ui/stream-presentation-coalescer.js +79 -0
  349. package/dist/integrations/pi/session-ui/system-clipboard.d.ts +20 -0
  350. package/dist/integrations/pi/session-ui/system-clipboard.js +156 -0
  351. package/dist/integrations/pi/session-ui/text-paste.d.ts +5 -0
  352. package/dist/integrations/pi/session-ui/text-paste.js +16 -0
  353. package/dist/{src/foundation/pi-tui-runtime-adapter → integrations/pi/tui-runtime}/adapter.d.ts +10 -1
  354. package/dist/{src/foundation/pi-tui-runtime-adapter → integrations/pi/tui-runtime}/adapter.js +255 -11
  355. package/dist/{src/foundation/pi-tui-runtime-adapter → integrations/pi/tui-runtime}/contracts.d.ts +32 -6
  356. package/dist/integrations/pi/tui-runtime/contracts.js +1 -0
  357. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +81 -0
  358. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +424 -0
  359. package/dist/integrations/pi/tui-runtime/index.d.ts +7 -0
  360. package/dist/integrations/pi/tui-runtime/index.js +7 -0
  361. package/dist/integrations/pi/tui-runtime/input-presentation-coordinator.d.ts +39 -0
  362. package/dist/integrations/pi/tui-runtime/input-presentation-coordinator.js +139 -0
  363. package/dist/integrations/pi/tui-runtime/mouse-report-input.d.ts +13 -0
  364. package/dist/integrations/pi/tui-runtime/mouse-report-input.js +59 -0
  365. package/dist/integrations/pi/tui-runtime/overlay-geometry.d.ts +32 -0
  366. package/dist/integrations/pi/tui-runtime/overlay-geometry.js +159 -0
  367. package/dist/{src/foundation/pi-tui-runtime-adapter → integrations/pi/tui-runtime}/presentation-adapter.d.ts +1 -1
  368. package/dist/native/darwin-arm64/manifest.json +4 -4
  369. package/dist/native/darwin-arm64/process-guardian +0 -0
  370. package/dist/native/linux-x64/manifest.json +3 -3
  371. package/dist/native/linux-x64/process-guardian +0 -0
  372. package/dist/native/win32-x64/manifest.json +3 -3
  373. package/dist/native/win32-x64/process-guardian.exe +0 -0
  374. package/dist/{src/product-identity.d.ts → product-identity.d.ts} +4 -4
  375. package/dist/{src/product-identity.js → product-identity.js} +7 -38
  376. package/dist/{src/product-identity.json → product-identity.json} +13 -27
  377. package/dist/runtime-payload-inventory.json +122333 -0
  378. package/dist/{src/foundation/ui-apps → ui/apps}/contracts.d.ts +23 -1
  379. package/dist/{src/foundation/ui-apps → ui/apps}/host.d.ts +1 -1
  380. package/dist/{src/foundation/ui-apps → ui/apps}/host.js +14 -10
  381. package/dist/{src/foundation/ui-apps → ui/apps}/registry.d.ts +1 -0
  382. package/dist/{src/foundation/ui-apps → ui/apps}/registry.js +1 -0
  383. package/dist/{src/foundation/ui-components → ui/components}/dialog-panel.js +5 -3
  384. package/dist/{src/foundation/ui-components → ui/components}/frame.d.ts +1 -0
  385. package/dist/{src/foundation/ui-components → ui/components}/frame.js +1 -0
  386. package/dist/{src/foundation/ui-components → ui/components}/index.d.ts +7 -0
  387. package/dist/{src/foundation/ui-components → ui/components}/index.js +7 -0
  388. package/dist/{src/foundation/ui-components → ui/components}/line-input.d.ts +2 -8
  389. package/dist/{src/foundation/ui-components → ui/components}/line-input.js +7 -28
  390. package/dist/{src/foundation/ui-components → ui/components}/list-view.d.ts +0 -6
  391. package/dist/{src/foundation/ui-components → ui/components}/list-view.js +14 -7
  392. package/dist/{src/foundation/ui-components → ui/components}/mouse.d.ts +10 -0
  393. package/dist/{src/foundation/ui-components → ui/components}/mouse.js +24 -0
  394. package/dist/ui/components/progress-status.d.ts +2 -0
  395. package/dist/ui/components/progress-status.js +4 -0
  396. package/dist/ui/components/prompt-input.d.ts +32 -0
  397. package/dist/ui/components/prompt-input.js +54 -0
  398. package/dist/ui/components/prompt-row.d.ts +14 -0
  399. package/dist/ui/components/prompt-row.js +20 -0
  400. package/dist/{src/foundation/ui-components → ui/components}/scrollbar.d.ts +26 -0
  401. package/dist/{src/foundation/ui-components → ui/components}/scrollbar.js +35 -0
  402. package/dist/ui/components/selection-copy.d.ts +24 -0
  403. package/dist/ui/components/selection-copy.js +39 -0
  404. package/dist/{src/foundation/ui-components → ui/components}/shortcuts.d.ts +1 -0
  405. package/dist/{src/foundation/ui-components → ui/components}/shortcuts.js +1 -0
  406. package/dist/ui/components/spans.d.ts +28 -0
  407. package/dist/ui/components/spans.js +266 -0
  408. package/dist/ui/components/submitted-prompt.d.ts +23 -0
  409. package/dist/ui/components/submitted-prompt.js +50 -0
  410. package/dist/{src/foundation/ui-components → ui/components}/surface.d.ts +0 -5
  411. package/dist/{src/foundation/ui-components → ui/components}/surface.js +1 -5
  412. package/dist/ui/components/text-selection.d.ts +62 -0
  413. package/dist/ui/components/text-selection.js +210 -0
  414. package/dist/{src/foundation/ui-components → ui/components}/text.d.ts +14 -0
  415. package/dist/{src/foundation/ui-components → ui/components}/text.js +67 -5
  416. package/dist/ui/components/transcript-viewport.d.ts +173 -0
  417. package/dist/ui/components/transcript-viewport.js +753 -0
  418. package/dist/ui/components/visible-hyperlinks.d.ts +26 -0
  419. package/dist/ui/components/visible-hyperlinks.js +97 -0
  420. package/dist/{src/foundation/owned-ui-settings → ui/settings}/declarations.d.ts +8 -1
  421. package/dist/ui/settings/declarations.js +94 -0
  422. package/dist/{src/foundation/owned-ui-settings → ui/settings}/migrations.d.ts +1 -1
  423. package/dist/{src/foundation/owned-ui-settings → ui/settings}/migrations.js +28 -2
  424. package/dist/{src/foundation/owned-ui-settings → ui/settings}/sections.d.ts +6 -19
  425. package/dist/{src/foundation/owned-ui-settings → ui/settings}/sections.js +41 -22
  426. package/dist/{src/foundation/owned-ui-settings → ui/settings}/session.d.ts +9 -17
  427. package/dist/ui/settings/session.js +164 -0
  428. package/dist/{src/foundation/owned-ui-settings → ui/settings}/store.d.ts +1 -0
  429. package/dist/{src/foundation/owned-ui-settings → ui/settings}/store.js +2 -1
  430. package/docs/architecture/boundaries.md +14 -10
  431. package/docs/architecture/code-documentation.md +77 -0
  432. package/docs/architecture/history-editor-provenance.md +100 -0
  433. package/docs/architecture/internal-naming.md +91 -0
  434. package/docs/architecture/process-guardian-provenance.md +3 -1
  435. package/docs/architecture/project-structure.md +69 -30
  436. package/docs/architecture/prompt-suggestions.md +68 -0
  437. package/docs/architecture/resource-and-data-policy.md +28 -2
  438. package/docs/architecture/response-copy-delivery.md +83 -0
  439. package/docs/architecture/tool-image-presentation.md +62 -0
  440. package/docs/architecture/toolchain.md +24 -10
  441. package/docs/architecture/ui-reference-provenance.md +59 -5
  442. package/docs/ci-release-runbook.md +236 -79
  443. package/docs/features/launch-profiles.md +24 -17
  444. package/docs/features/modal-content-interaction.md +37 -0
  445. package/docs/features/prompt-history.md +149 -0
  446. package/docs/manual-code-streaming-cleanup.md +88 -0
  447. package/docs/manual-ghost-link-baseline.md +89 -0
  448. package/docs/manual-launch-instance-acceptance.md +12 -35
  449. package/docs/manual-owned-ui-checkpoint.md +78 -0
  450. package/docs/manual-pi-boundary-candidate.md +4 -5
  451. package/docs/manual-terminal-colour-check.md +4 -3
  452. package/docs/openspec-archive-automation.md +124 -0
  453. package/docs/repository-governance-live-acceptance.md +77 -0
  454. package/package.json +45 -28
  455. package/dist/src/cli/capabilities.d.ts +0 -15
  456. package/dist/src/cli/dispatch.js +0 -142
  457. package/dist/src/cli/version-stats.js +0 -72
  458. package/dist/src/composition/index.d.ts +0 -48
  459. package/dist/src/composition/index.js +0 -258
  460. package/dist/src/features/launch/intent.d.ts +0 -7
  461. package/dist/src/features/launch/intent.js +0 -4
  462. package/dist/src/features/launch/profiles.d.ts +0 -12
  463. package/dist/src/features/launch/profiles.js +0 -26
  464. package/dist/src/features/owned-ui/run.js +0 -15
  465. package/dist/src/foundation/lifecycle/paths.d.ts +0 -10
  466. package/dist/src/foundation/owned-ui-contracts/index.d.ts +0 -3
  467. package/dist/src/foundation/owned-ui-contracts/index.js +0 -3
  468. package/dist/src/foundation/owned-ui-settings/declarations.js +0 -39
  469. package/dist/src/foundation/owned-ui-settings/session.js +0 -145
  470. package/dist/src/foundation/pi-component-adapter/shell-editor-autocomplete.js +0 -162
  471. package/dist/src/foundation/pi-component-adapter/shell-presenters-transcript.d.ts +0 -57
  472. package/dist/src/foundation/pi-component-adapter/shell-shared-facade.d.ts +0 -116
  473. package/dist/src/foundation/pi-component-adapter/upstream/components/earendil-announcement.js +0 -19
  474. package/dist/src/foundation/pi-component-adapter/upstream/components/owned-editor.d.ts +0 -18
  475. package/dist/src/foundation/pi-component-adapter/upstream/components/owned-editor.js +0 -55
  476. package/dist/src/foundation/pi-engine-adapter/settings-integration.d.ts +0 -55
  477. package/dist/src/foundation/pi-owned-ui-integration/index.d.ts +0 -2
  478. package/dist/src/foundation/pi-owned-ui-integration/index.js +0 -2
  479. package/dist/src/foundation/pi-owned-ui-integration/route-host.d.ts +0 -29
  480. package/dist/src/foundation/pi-owned-ui-integration/session-shell.d.ts +0 -106
  481. package/dist/src/foundation/pi-owned-ui-integration/session-shell.js +0 -1518
  482. package/dist/src/foundation/pi-tui-runtime-adapter/index.d.ts +0 -4
  483. package/dist/src/foundation/pi-tui-runtime-adapter/index.js +0 -4
  484. package/dist/src/foundation/release/bootstrap.d.ts +0 -29
  485. package/dist/src/foundation/release/cohort-state.d.ts +0 -70
  486. package/dist/src/foundation/release/cohort-state.js +0 -202
  487. package/dist/src/foundation/release/release-gc.d.ts +0 -5
  488. package/dist/src/foundation/release/release-gc.js +0 -16
  489. package/dist/src/foundation/supervision/index.d.ts +0 -3
  490. package/dist/src/foundation/supervision/index.js +0 -3
  491. package/dist/src/foundation/supervision/main.d.ts +0 -1
  492. package/dist/src/foundation/supervision/main.js +0 -41
  493. package/dist/src/foundation/supervision/paths.d.ts +0 -1
  494. package/dist/src/foundation/supervision/paths.js +0 -1
  495. package/dist/src/foundation/supervision/server.d.ts +0 -22
  496. package/dist/src/foundation/ui-components/spans.d.ts +0 -7
  497. package/dist/src/foundation/ui-components/spans.js +0 -59
  498. package/docs/manual-transparent-checkpoint.md +0 -53
  499. /package/dist/{src/cli → cli}/index.d.ts +0 -0
  500. /package/dist/{src/cli → cli}/index.js +0 -0
  501. /package/dist/{src/cli → cli}/version.d.ts +0 -0
  502. /package/dist/{src/cli → cli}/version.js +0 -0
  503. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/capability-ports.js +0 -0
  504. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/domain-validation.d.ts +0 -0
  505. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/domain.js +0 -0
  506. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/index.d.ts +0 -0
  507. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/index.js +0 -0
  508. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/model.d.ts +0 -0
  509. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/model.js +0 -0
  510. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/package-ports.js +0 -0
  511. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/ports.d.ts +0 -0
  512. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/ports.js +0 -0
  513. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/serialization.d.ts +0 -0
  514. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/serialization.js +0 -0
  515. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/validation.d.ts +0 -0
  516. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/validation.js +0 -0
  517. /package/dist/{src/foundation/owned-ui-contracts → contracts/owned-ui}/extension-ui.d.ts +0 -0
  518. /package/dist/{src/foundation/owned-ui-contracts → contracts/owned-ui}/extension-ui.js +0 -0
  519. /package/dist/{src/foundation/owned-ui-contracts → contracts/owned-ui}/model.js +0 -0
  520. /package/dist/{src/foundation/presentation-contracts → contracts/presentation}/index.js +0 -0
  521. /package/dist/{src/foundation/workspace-contracts → contracts/workspace}/index.d.ts +0 -0
  522. /package/dist/{src/foundation/workspace-contracts → contracts/workspace}/index.js +0 -0
  523. /package/dist/{src/foundation/workspace-contracts → contracts/workspace}/model.d.ts +0 -0
  524. /package/dist/{src/foundation/workspace-contracts → contracts/workspace}/model.js +0 -0
  525. /package/dist/{src/foundation/workspace-contracts → contracts/workspace}/validation.d.ts +0 -0
  526. /package/dist/{src/foundation/workspace-contracts → contracts/workspace}/validation.js +0 -0
  527. /package/dist/{src/features → features}/launch/development-launch.d.ts +0 -0
  528. /package/dist/{src/features → features}/launch/initialize-profile.d.ts +0 -0
  529. /package/dist/{src/features → features}/launch/initialize-profile.js +0 -0
  530. /package/dist/{src/features → features}/launch/runtime-selection.js +0 -0
  531. /package/dist/{src/features → features}/workspace/capabilities.js +0 -0
  532. /package/dist/{src/features → features}/workspace/index.d.ts +0 -0
  533. /package/dist/{src/features → features}/workspace/index.js +0 -0
  534. /package/dist/{src/features → features}/workspace/presentation.d.ts +0 -0
  535. /package/dist/{src/features → features}/workspace/presentation.js +0 -0
  536. /package/dist/{src/features → features}/workspace/reconciliation.d.ts +0 -0
  537. /package/dist/{src/features → features}/workspace/reconciliation.js +0 -0
  538. /package/dist/{src/foundation → foundation}/launch-guardian/index.d.ts +0 -0
  539. /package/dist/{src/foundation → foundation}/launch-guardian/index.js +0 -0
  540. /package/dist/{src/foundation → foundation}/lifecycle/commands.d.ts +0 -0
  541. /package/dist/{src/foundation → foundation}/lifecycle/commands.js +0 -0
  542. /package/dist/{src/foundation → foundation}/lifecycle/launch-instance.d.ts +0 -0
  543. /package/dist/{src/foundation → foundation}/lifecycle/launch-instance.js +0 -0
  544. /package/dist/{src/foundation → foundation}/native-host-protocol/evidence.d.ts +0 -0
  545. /package/dist/{src/foundation → foundation}/native-host-protocol/evidence.js +0 -0
  546. /package/dist/{src/foundation → foundation}/native-host-protocol/index.d.ts +0 -0
  547. /package/dist/{src/foundation → foundation}/native-host-protocol/index.js +0 -0
  548. /package/dist/{src/foundation → foundation}/native-host-protocol/proof-gate.d.ts +0 -0
  549. /package/dist/{src/foundation → foundation}/native-host-protocol/proof-gate.js +0 -0
  550. /package/dist/{src/foundation → foundation}/process-containment/artifact.d.ts +0 -0
  551. /package/dist/{src/foundation → foundation}/process-containment/artifact.js +0 -0
  552. /package/dist/{src/foundation → foundation}/process-containment/contracts.d.ts +0 -0
  553. /package/dist/{src/foundation → foundation}/process-containment/contracts.js +0 -0
  554. /package/dist/{src/foundation → foundation}/protocol/index.d.ts +0 -0
  555. /package/dist/{src/foundation → foundation}/protocol/index.js +0 -0
  556. /package/dist/{src/foundation → foundation}/release/cohort-selection.d.ts +0 -0
  557. /package/dist/{src/foundation → foundation}/release/cohort-selection.js +0 -0
  558. /package/dist/{src/foundation → foundation}/release/concurrency.d.ts +0 -0
  559. /package/dist/{src/foundation → foundation}/release/concurrency.js +0 -0
  560. /package/dist/{src/foundation → foundation}/release/process-cleanup.d.ts +0 -0
  561. /package/dist/{src/foundation → foundation}/release/process-cleanup.js +0 -0
  562. /package/dist/{src/foundation → foundation}/release/stable-release.d.ts +0 -0
  563. /package/dist/{src/foundation → foundation}/release/stable-release.js +0 -0
  564. /package/dist/{src/foundation → foundation}/storage/index.d.ts +0 -0
  565. /package/dist/{src/foundation → foundation}/storage/index.js +0 -0
  566. /package/dist/{src/foundation → foundation}/structured-agent-runtime/index.d.ts +0 -0
  567. /package/dist/{src/foundation → foundation}/structured-agent-runtime/index.js +0 -0
  568. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/components.js +0 -0
  569. /package/dist/{src/foundation/pi-owned-ui-integration/route-host.js → integrations/pi/components/editor-interaction.js} +0 -0
  570. /package/dist/{src/foundation/pi-tui-runtime-adapter/contracts.js → integrations/pi/components/prompt-input-port.js} +0 -0
  571. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/resources/builtin-themes.d.ts +0 -0
  572. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/resources/builtin-themes.js +0 -0
  573. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-editor-autocomplete.d.ts +0 -0
  574. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-extension-ui.js +0 -0
  575. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/theme.d.ts +0 -0
  576. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/theme.js +0 -0
  577. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/countdown-timer.d.ts +0 -0
  578. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/countdown-timer.js +0 -0
  579. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/custom-entry.d.ts +0 -0
  580. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/custom-entry.js +0 -0
  581. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/daxnuts.d.ts +0 -0
  582. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/daxnuts.js +0 -0
  583. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/earendil-announcement.d.ts +0 -0
  584. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/extension-editor.d.ts +0 -0
  585. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/extension-editor.js +0 -0
  586. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/first-time-setup.d.ts +0 -0
  587. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/first-time-setup.js +0 -0
  588. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/markdown-transform.d.ts +0 -0
  589. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/markdown-transform.js +0 -0
  590. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/mermaid.d.ts +0 -0
  591. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/mermaid.js +0 -0
  592. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/session-selector-search.d.ts +0 -0
  593. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/session-selector-search.js +0 -0
  594. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/session-selector.d.ts +0 -0
  595. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/session-selector.js +0 -0
  596. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/skill-invocation-message.d.ts +0 -0
  597. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/skill-invocation-message.js +0 -0
  598. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/status-indicator.d.ts +0 -0
  599. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/status-indicator.js +0 -0
  600. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/tree-selector.d.ts +0 -0
  601. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/tree-selector.js +0 -0
  602. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/trust-selector.d.ts +0 -0
  603. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/trust-selector.js +0 -0
  604. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/external-editor.d.ts +0 -0
  605. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/external-editor.js +0 -0
  606. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/model-search.d.ts +0 -0
  607. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/model-search.js +0 -0
  608. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/theme/theme-controller.d.ts +0 -0
  609. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/theme/theme-controller.js +0 -0
  610. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/theme/theme.d.ts +0 -0
  611. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/theme/theme.js +0 -0
  612. /package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/pi-settings-metadata.json +0 -0
  613. /package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/public-main-entry.d.ts +0 -0
  614. /package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/public-main-entry.js +0 -0
  615. /package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/workflows.js +0 -0
  616. /package/dist/{src/foundation/pi-tui-runtime-adapter → integrations/pi/tui-runtime}/conformance.d.ts +0 -0
  617. /package/dist/{src/foundation/pi-tui-runtime-adapter → integrations/pi/tui-runtime}/conformance.js +0 -0
  618. /package/dist/{src/foundation/pi-tui-runtime-adapter → integrations/pi/tui-runtime}/presentation-adapter.js +0 -0
  619. /package/dist/{src/foundation/ui-apps → ui/apps}/contracts.js +0 -0
  620. /package/dist/{src/foundation/ui-apps → ui/apps}/index.d.ts +0 -0
  621. /package/dist/{src/foundation/ui-apps → ui/apps}/index.js +0 -0
  622. /package/dist/{src/foundation/ui-components → ui/components}/dialog-panel.d.ts +0 -0
  623. /package/dist/{src/foundation/ui-components → ui/components}/label.d.ts +0 -0
  624. /package/dist/{src/foundation/ui-components → ui/components}/label.js +0 -0
  625. /package/dist/{src/foundation/ui-components → ui/components}/list-block.d.ts +0 -0
  626. /package/dist/{src/foundation/ui-components → ui/components}/list-block.js +0 -0
  627. /package/dist/{src/foundation/ui-components → ui/components}/pane.d.ts +0 -0
  628. /package/dist/{src/foundation/ui-components → ui/components}/pane.js +0 -0
  629. /package/dist/{src/foundation/ui-components → ui/components}/revision.d.ts +0 -0
  630. /package/dist/{src/foundation/ui-components → ui/components}/revision.js +0 -0
  631. /package/dist/{src/foundation/ui-components → ui/components}/status-line.d.ts +0 -0
  632. /package/dist/{src/foundation/ui-components → ui/components}/status-line.js +0 -0
  633. /package/dist/{src/foundation/ui-components → ui/components}/stepper.d.ts +0 -0
  634. /package/dist/{src/foundation/ui-components → ui/components}/stepper.js +0 -0
  635. /package/dist/{src/foundation/ui-components → ui/components}/theme.d.ts +0 -0
  636. /package/dist/{src/foundation/ui-components → ui/components}/theme.js +0 -0
  637. /package/dist/{src/foundation/ui-components → ui/components}/value-menu.d.ts +0 -0
  638. /package/dist/{src/foundation/ui-components → ui/components}/value-menu.js +0 -0
  639. /package/dist/{src/foundation/owned-ui-settings → ui/settings}/index.d.ts +0 -0
  640. /package/dist/{src/foundation/owned-ui-settings → ui/settings}/index.js +0 -0
  641. /package/dist/{src/foundation/owned-ui-settings → ui/settings}/resolution.d.ts +0 -0
  642. /package/dist/{src/foundation/owned-ui-settings → ui/settings}/resolution.js +0 -0
@@ -1,9 +1,10 @@
1
1
  import { type ReleaseIdentity } from "./release.js";
2
+ import { type ReadCertifiedDependencyLayerOptions, type RuntimePayloadInventory } from "./dependency-layer.js";
2
3
  export declare const RELEASE_MANIFEST_FILENAME: string;
3
4
  export interface MaterializedRelease extends ReleaseIdentity {
4
5
  readonly releaseRoot: string;
5
6
  }
6
- export type ReleaseContentOperation = "source-read" | "candidate-write" | "verification-read";
7
+ export type ReleaseContentOperation = "source-read" | "candidate-write" | "layer-write" | "layer-reuse" | "verification-read";
7
8
  export interface ReleaseContentOperationEvent {
8
9
  readonly operation: ReleaseContentOperation;
9
10
  readonly path: string;
@@ -15,6 +16,7 @@ export interface MaterializeReleaseOptions {
15
16
  readonly fileCount: number;
16
17
  }) => void;
17
18
  readonly onOperation?: (event: ReleaseContentOperationEvent) => void;
19
+ readonly onRuntimeInventory?: (inventory: RuntimePayloadInventory) => void;
18
20
  /** Test seam for deterministic write-failure coverage. */
19
21
  readonly writeCandidateFile?: (path: string, bytes: Uint8Array, mode: number) => Promise<void>;
20
22
  }
@@ -26,18 +28,22 @@ export interface CertifiedReleaseRecord {
26
28
  readonly releaseRoot: string;
27
29
  readonly packageVersion?: string;
28
30
  readonly contentDigest: string;
31
+ /** Absent on records written before releases declared a handoff contract. */
32
+ readonly launchContract?: string;
29
33
  }
34
+ /** Process-authority compatibility controls for metadata-only release loading. */
35
+ export type ReadCertifiedReleaseManifestOptions = ReadCertifiedDependencyLayerOptions;
30
36
  export declare function materializeRelease(packageRoot: string, dataDir: string, options?: MaterializeReleaseOptions): Promise<MaterializedRelease>;
31
37
  /** Consume proof that this exact object was freshly materialized or fully verified in this process. */
32
38
  export declare function consumeMaterializationProof(release: MaterializedRelease): boolean;
33
- export declare function readMaterializedRelease(releaseRoot: string): Promise<MaterializedRelease>;
39
+ export declare function readMaterializedRelease(releaseRoot: string, selectedStoreRoot?: string): Promise<MaterializedRelease>;
34
40
  /**
35
41
  * Load metadata for a release whose bytes were already certified by the
36
42
  * current parent process or an authenticated live supervisor. Callers must
37
43
  * establish one of those preconditions; untrusted releases require full
38
44
  * verification.
39
45
  */
40
- export declare function readCertifiedReleaseManifest(record: CertifiedReleaseRecord, selectedStoreRoot: string): Promise<MaterializedRelease>;
46
+ export declare function readCertifiedReleaseManifest(record: CertifiedReleaseRecord, selectedStoreRoot: string, options?: ReadCertifiedReleaseManifestOptions): Promise<MaterializedRelease>;
41
47
  export declare function verifyMaterializedRelease(releaseRoot: string, expected?: ReleaseIdentity, selectedStoreRoot?: string, options?: VerifyMaterializedReleaseOptions): Promise<MaterializedRelease>;
42
48
  export declare function assertImmutableExecutionRoot(release: MaterializedRelease, dataDir: string): Promise<void>;
43
49
  export declare function resolveReleaseEntryPoint(release: MaterializedRelease, entryPoint: string): Promise<string>;
@@ -1,9 +1,12 @@
1
1
  import { createHash, randomUUID } from "node:crypto";
2
- import { chmod, lstat, mkdir, readFile, realpath, rename, rm, writeFile } from "node:fs/promises";
2
+ import { chmod, lstat, mkdir, readFile, realpath, rename, rm, symlink, writeFile } from "node:fs/promises";
3
3
  import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
4
- import { PRODUCT_PACKAGE_NAME, createReleaseIdentity, digestManifestFiles, discoverReleasePayload, releaseFileIdentity, resolveWithin, } from "./release.js";
4
+ import { PRODUCT_PACKAGE_NAME, createReleaseIdentity, discoverReleasePayload, releaseFileIdentity, resolveWithin, } from "./release.js";
5
5
  import { PRODUCT_IDENTITY, PRODUCT_TEXT } from "../../product-identity.js";
6
+ import { assertCurrentLaunchContract, isCurrentLaunchContract, readLaunchContext } from "../launch-context/index.js";
6
7
  import { mapWithConcurrency } from "./concurrency.js";
8
+ import { assertImmutableFileMode } from "./immutable-platform.js";
9
+ import { dependencyReference, materializeDependencyLayer, readCertifiedDependencyLayer, selectPublishedDependencyRuntimePayload, verifyDependencyLayer, } from "./dependency-layer.js";
7
10
  const RELEASE_FILE_IO_CONCURRENCY = 32;
8
11
  const certificationReady = new WeakSet();
9
12
  export const RELEASE_MANIFEST_FILENAME = PRODUCT_IDENTITY.manifest.releaseFilename;
@@ -11,17 +14,35 @@ export async function materializeRelease(packageRoot, dataDir, options = {}) {
11
14
  const payload = await discoverReleasePayload(packageRoot, {
12
15
  onSourceRead: (path, bytes) => options.onOperation?.({ operation: "source-read", path, bytes }),
13
16
  });
17
+ assertCurrentLaunchContract(payload);
14
18
  const storeRoot = resolve(dataDir, "releases");
15
19
  await mkdir(storeRoot, { recursive: true, mode: 0o700 });
16
- options.onProgress?.({ phase: "copying", fileCount: payload.paths.length });
20
+ const dependencyPaths = payload.paths.filter(path => path.startsWith("node_modules/"));
21
+ const productPaths = payload.paths.filter(path => !path.startsWith("node_modules/"));
22
+ const selectedDependencies = await selectPublishedDependencyRuntimePayload(payload.packageRoot, dependencyPaths);
23
+ options.onRuntimeInventory?.(selectedDependencies.inventory);
24
+ const layerOperations = [];
25
+ const layer = await materializeDependencyLayer(payload.packageRoot, dataDir, selectedDependencies.paths, {
26
+ inventory: selectedDependencies.inventory,
27
+ cachedFiles: payload.cachedFiles,
28
+ onOperation: event => layerOperations.push(event),
29
+ ...(options.writeCandidateFile === undefined ? {} : { writeCandidateFile: options.writeCandidateFile }),
30
+ });
31
+ const layerReferences = layer === null ? [] : [dependencyReference(layer)];
32
+ options.onProgress?.({
33
+ phase: "copying",
34
+ fileCount: productPaths.length + (layer?.reused === false ? layer.files.length : 0),
35
+ });
36
+ for (const event of layerOperations)
37
+ options.onOperation?.(event);
17
38
  const candidate = resolveWithin(storeRoot, `.candidate-${randomUUID()}`);
18
39
  await mkdir(candidate, { recursive: false, mode: 0o700 });
19
40
  try {
20
- const directories = [...new Set(payload.paths.map(path => dirname(resolveWithin(candidate, path))))];
41
+ const directories = [...new Set(productPaths.map(path => dirname(resolveWithin(candidate, path))))];
21
42
  await mapWithConcurrency(directories, RELEASE_FILE_IO_CONCURRENCY, async (directory) => {
22
43
  await mkdir(directory, { recursive: true, mode: 0o700 });
23
44
  });
24
- const files = await mapWithConcurrency(payload.paths, RELEASE_FILE_IO_CONCURRENCY, async (path) => {
45
+ const files = await mapWithConcurrency(productPaths, RELEASE_FILE_IO_CONCURRENCY, async (path) => {
25
46
  const source = resolveWithin(payload.packageRoot, path);
26
47
  const destination = resolveWithin(candidate, path);
27
48
  const metadata = await lstat(source);
@@ -41,7 +62,12 @@ export async function materializeRelease(packageRoot, dataDir, options = {}) {
41
62
  options.onOperation?.({ operation: "candidate-write", path, bytes: bytes.length });
42
63
  return releaseFileIdentity(path, bytes, (metadata.mode & 0o111) !== 0);
43
64
  });
44
- const identity = createReleaseIdentity(payload.packageRoot, payload.packageVersion, files);
65
+ const identity = createReleaseIdentity(payload.packageRoot, payload.packageVersion, files, layerReferences, payload.launchContract);
66
+ if (layer !== null) {
67
+ const binding = resolveWithin(candidate, "node_modules");
68
+ const target = resolveWithin(layer.layerRoot, "node_modules");
69
+ await symlink(target, binding, process.platform === "win32" ? "junction" : "dir");
70
+ }
45
71
  const releaseRoot = resolveWithin(storeRoot, identity.releaseId);
46
72
  if (await lstat(releaseRoot).catch(() => null)) {
47
73
  await rm(candidate, { recursive: true, force: true });
@@ -71,10 +97,10 @@ export function consumeMaterializationProof(release) {
71
97
  certificationReady.delete(release);
72
98
  return true;
73
99
  }
74
- export async function readMaterializedRelease(releaseRoot) {
100
+ export async function readMaterializedRelease(releaseRoot, selectedStoreRoot) {
75
101
  const canonical = await realpath(releaseRoot);
76
102
  const manifest = JSON.parse(await readFile(resolve(canonical, RELEASE_MANIFEST_FILENAME), "utf8"));
77
- return await verifyMaterializedRelease(canonical, manifest);
103
+ return certificationReadyRelease(await verifyMaterializedRelease(canonical, manifest, selectedStoreRoot));
78
104
  }
79
105
  /**
80
106
  * Load metadata for a release whose bytes were already certified by the
@@ -82,9 +108,10 @@ export async function readMaterializedRelease(releaseRoot) {
82
108
  * establish one of those preconditions; untrusted releases require full
83
109
  * verification.
84
110
  */
85
- export async function readCertifiedReleaseManifest(record, selectedStoreRoot) {
111
+ export async function readCertifiedReleaseManifest(record, selectedStoreRoot, options = {}) {
86
112
  const canonical = await realpath(record.releaseRoot);
87
- assertContained(await realpath(selectedStoreRoot), canonical, "release root is outside the selected release store");
113
+ const canonicalStoreRoot = await realpath(selectedStoreRoot);
114
+ assertContained(canonicalStoreRoot, canonical, "release root is outside the selected release store");
88
115
  const manifest = JSON.parse(await readFile(resolveWithin(canonical, RELEASE_MANIFEST_FILENAME), "utf8"));
89
116
  validateManifest(manifest);
90
117
  if (manifest.releaseId !== record.releaseId || manifest.contentDigest !== record.contentDigest
@@ -93,12 +120,13 @@ export async function readCertifiedReleaseManifest(record, selectedStoreRoot) {
93
120
  }
94
121
  if (canonical.split(sep).at(-1) !== manifest.releaseId)
95
122
  throw new Error(`release directory does not match identity ${manifest.releaseId}`);
123
+ await verifyReleaseDependencies(canonical, canonicalStoreRoot, manifest.dependencyLayers ?? [], false, {}, options);
96
124
  return { ...manifest, releaseRoot: canonical };
97
125
  }
98
126
  export async function verifyMaterializedRelease(releaseRoot, expected, selectedStoreRoot, options = {}) {
99
127
  const canonical = await realpath(releaseRoot);
100
- if (selectedStoreRoot)
101
- assertContained(await realpath(selectedStoreRoot), canonical, "release root is outside the selected release store");
128
+ const canonicalStoreRoot = selectedStoreRoot ? await realpath(selectedStoreRoot) : await realpath(dirname(canonical));
129
+ assertContained(canonicalStoreRoot, canonical, "release root is outside the selected release store");
102
130
  const manifestPath = resolveWithin(canonical, RELEASE_MANIFEST_FILENAME);
103
131
  const manifest = JSON.parse(await readFile(manifestPath, "utf8"));
104
132
  validateManifest(manifest);
@@ -111,15 +139,16 @@ export async function verifyMaterializedRelease(releaseRoot, expected, selectedS
111
139
  await mapWithConcurrency(manifest.files, RELEASE_FILE_IO_CONCURRENCY, async (file) => {
112
140
  await verifyFile(canonical, file, options);
113
141
  });
114
- const recomputed = digestManifestFiles(manifest.files);
142
+ const recomputed = createReleaseIdentity(manifest.packageRoot, manifest.packageVersion, manifest.files, manifest.dependencyLayers ?? [], manifest.launchContract).contentDigest;
115
143
  if (recomputed !== manifest.contentDigest)
116
144
  throw new Error(`release content digest mismatch for ${manifest.releaseId}`);
145
+ await verifyReleaseDependencies(canonical, canonicalStoreRoot, manifest.dependencyLayers ?? [], true, options);
117
146
  return { ...manifest, releaseRoot: canonical };
118
147
  }
119
148
  export async function assertImmutableExecutionRoot(release, dataDir) {
120
149
  const storeRoot = await realpath(resolve(dataDir, "releases"));
121
150
  assertContained(storeRoot, release.releaseRoot, "release root is outside the selected release store");
122
- const selectedRoot = process.env[PRODUCT_IDENTITY.environment.releaseRoot];
151
+ const selectedRoot = readLaunchContext(process.env, "release").releaseRoot;
123
152
  if (!selectedRoot)
124
153
  throw new Error(PRODUCT_TEXT.diagnostic("persistent process has no immutable release root"));
125
154
  const selected = await realpath(selectedRoot);
@@ -135,6 +164,25 @@ export async function resolveReleaseEntryPoint(release, entryPoint) {
135
164
  assertContained(release.releaseRoot, canonical, "entry point resolves outside the selected release root");
136
165
  return canonical;
137
166
  }
167
+ async function verifyReleaseDependencies(releaseRoot, storeRoot, references, fullVerification, options = {}, certificationOptions = {}) {
168
+ if (references.length === 0)
169
+ return;
170
+ if (references.length !== 1)
171
+ throw new Error("release currently supports exactly one dependency layer");
172
+ const dataDir = dirname(storeRoot);
173
+ const reference = references[0];
174
+ const layer = fullVerification
175
+ ? await verifyDependencyLayer(dataDir, reference, event => options.onOperation?.({ operation: event.operation, path: event.path, bytes: event.bytes }))
176
+ : await readCertifiedDependencyLayer(dataDir, reference.layerId, reference, certificationOptions);
177
+ const binding = resolveWithin(releaseRoot, reference.binding);
178
+ const metadata = await lstat(binding);
179
+ if (!metadata.isSymbolicLink())
180
+ throw new Error(`release dependency binding is not managed: ${binding}`);
181
+ const target = await realpath(binding);
182
+ const expected = await realpath(resolveWithin(layer.layerRoot, "node_modules"));
183
+ if (target !== expected)
184
+ throw new Error(`release dependency binding targets unexpected content: ${target}`);
185
+ }
138
186
  async function verifyFile(root, file, options) {
139
187
  const path = resolveWithin(root, file.path);
140
188
  const metadata = await lstat(path).catch(() => null);
@@ -142,6 +190,7 @@ async function verifyFile(root, file, options) {
142
190
  throw new Error(`release candidate is incomplete: ${file.path}`);
143
191
  if (metadata.size !== file.bytes)
144
192
  throw new Error(`release file size mismatch: ${file.path}`);
193
+ assertImmutableFileMode(metadata, path);
145
194
  const bytes = await readFile(path);
146
195
  options.onOperation?.({ operation: "verification-read", path: file.path, bytes: bytes.length });
147
196
  const digest = createHash("sha256").update(bytes).digest("hex");
@@ -153,12 +202,20 @@ function certificationReadyRelease(release) {
153
202
  return release;
154
203
  }
155
204
  function validateManifest(value) {
205
+ if (value.launchContract !== undefined && !isCurrentLaunchContract(value)) {
206
+ throw new Error(PRODUCT_TEXT.diagnostic(`release manifest declares an unsupported launch contract: ${String(value.launchContract)}`));
207
+ }
156
208
  if (value.packageName !== PRODUCT_PACKAGE_NAME || typeof value.packageVersion !== "string")
157
209
  throw new Error(PRODUCT_TEXT.diagnostic("release manifest metadata is invalid"));
158
210
  if (!/^[a-f0-9]{64}$/.test(value.contentDigest) || !/^[0-9A-Za-z.+_-]+-[a-f0-9]{20}$/.test(value.releaseId))
159
211
  throw new Error(PRODUCT_TEXT.diagnostic("release identity is invalid"));
160
212
  if (!Array.isArray(value.files) || value.files.length === 0)
161
213
  throw new Error("release manifest contains no files");
214
+ if (value.dependencyLayers !== undefined && (!Array.isArray(value.dependencyLayers) || value.dependencyLayers.length === 0
215
+ || value.dependencyLayers.some(layer => !/^dependencies-[a-f0-9]{32}$/.test(layer.layerId)
216
+ || !/^[a-f0-9]{64}$/.test(layer.contentDigest) || layer.binding !== "node_modules"))) {
217
+ throw new Error("release dependency-layer references are invalid");
218
+ }
162
219
  for (const file of value.files) {
163
220
  if (typeof file.path !== "string" || file.path.length === 0 || file.path.includes("\\") || file.path.startsWith("/") || file.path.split("/").includes("..")) {
164
221
  throw new Error(`invalid release manifest path: ${String(file.path)}`);
@@ -166,6 +223,9 @@ function validateManifest(value) {
166
223
  if (!Number.isSafeInteger(file.bytes) || file.bytes < 0 || !/^[a-f0-9]{64}$/.test(file.sha256))
167
224
  throw new Error(`invalid release manifest file identity: ${file.path}`);
168
225
  }
226
+ const expected = createReleaseIdentity(value.packageRoot, value.packageVersion, value.files, value.dependencyLayers ?? [], value.launchContract);
227
+ if (expected.contentDigest !== value.contentDigest)
228
+ throw new Error("release manifest content/contract digest mismatch");
169
229
  }
170
230
  function assertContained(parent, child, message) {
171
231
  const fromParent = relative(parent, child);
@@ -1,3 +1,4 @@
1
+ import type { DependencyLayerReference } from "./dependency-layer.js";
1
2
  export declare const PRODUCT_PACKAGE_NAME: string;
2
3
  export interface ReleaseFileIdentity {
3
4
  readonly path: string;
@@ -11,12 +12,16 @@ export interface ReleaseIdentity {
11
12
  readonly contentDigest: string;
12
13
  readonly releaseId: string;
13
14
  readonly packageRoot: string;
15
+ readonly launchContract?: string;
14
16
  readonly files: readonly ReleaseFileIdentity[];
17
+ /** Absent for legacy full-copy releases. */
18
+ readonly dependencyLayers?: readonly DependencyLayerReference[];
15
19
  }
16
20
  export interface DiscoveredReleasePayload {
17
21
  readonly packageRoot: string;
18
22
  readonly packageVersion: string;
19
23
  readonly paths: readonly string[];
24
+ readonly launchContract?: string;
20
25
  /** Package manifests already read to discover the dependency closure. */
21
26
  readonly cachedFiles: ReadonlyMap<string, Buffer>;
22
27
  }
@@ -31,7 +36,7 @@ export declare function discoverReleasePayload(packageRoot: string, options?: Di
31
36
  * content.
32
37
  */
33
38
  export declare function deriveReleaseIdentity(packageRoot: string): Promise<ReleaseIdentity>;
34
- export declare function createReleaseIdentity(packageRoot: string, packageVersion: string, files: readonly ReleaseFileIdentity[]): ReleaseIdentity;
39
+ export declare function createReleaseIdentity(packageRoot: string, packageVersion: string, files: readonly ReleaseFileIdentity[], dependencyLayers?: readonly DependencyLayerReference[], launchContract?: string): ReleaseIdentity;
35
40
  export declare function releaseFileIdentity(path: string, bytes: Uint8Array, executable: boolean): ReleaseFileIdentity;
36
41
  export declare function digestManifestFiles(files: readonly ReleaseFileIdentity[]): string;
37
42
  export declare function resolveWithin(root: string, candidate: string): string;
@@ -31,6 +31,7 @@ export async function discoverReleasePayload(packageRoot, options = {}) {
31
31
  packageRoot: canonicalRoot,
32
32
  packageVersion: manifest.version,
33
33
  paths: [...paths].sort(),
34
+ ...(typeof manifest.privateLaunchContract === "string" ? { launchContract: manifest.privateLaunchContract } : {}),
34
35
  cachedFiles,
35
36
  };
36
37
  }
@@ -49,17 +50,27 @@ export async function deriveReleaseIdentity(packageRoot) {
49
50
  const bytes = payload.cachedFiles.get(path) ?? await readFile(absolute);
50
51
  return releaseFileIdentity(path, bytes, (metadata.mode & 0o111) !== 0);
51
52
  });
52
- return createReleaseIdentity(payload.packageRoot, payload.packageVersion, files);
53
+ return createReleaseIdentity(payload.packageRoot, payload.packageVersion, files, [], payload.launchContract);
53
54
  }
54
- export function createReleaseIdentity(packageRoot, packageVersion, files) {
55
- const contentDigest = digestManifestFiles(files);
55
+ export function createReleaseIdentity(packageRoot, packageVersion, files, dependencyLayers = [], launchContract) {
56
+ const fileDigest = digestManifestFiles(files);
57
+ const productDigest = launchContract === undefined ? fileDigest
58
+ : createHash("sha256").update(`launch-contract\0${launchContract}\0${fileDigest}`).digest("hex");
59
+ const contentDigest = dependencyLayers.length === 0
60
+ ? productDigest
61
+ : createHash("sha256")
62
+ .update(`product\0${productDigest}\n`)
63
+ .update(dependencyLayers.map(layer => `${layer.layerId}\0${layer.contentDigest}\0${layer.binding}\n`).join(""))
64
+ .digest("hex");
56
65
  return {
57
66
  packageName: PRODUCT_PACKAGE_NAME,
58
67
  packageVersion,
59
68
  contentDigest,
60
69
  releaseId: `${packageVersion}-${contentDigest.slice(0, 20)}`,
61
70
  packageRoot,
71
+ ...(launchContract === undefined ? {} : { launchContract }),
62
72
  files: [...files].sort(compareReleaseFiles),
73
+ ...(dependencyLayers.length === 0 ? {} : { dependencyLayers: [...dependencyLayers] }),
63
74
  };
64
75
  }
65
76
  export function releaseFileIdentity(path, bytes, executable) {
@@ -143,7 +154,7 @@ async function findInstalledDependency(root, requesterRoot, name) {
143
154
  const metadata = await lstat(candidate).catch(() => null);
144
155
  if (metadata?.isDirectory() && !metadata.isSymbolicLink())
145
156
  return candidate;
146
- // A linked dependency directory is how this installation unifies a module
157
+ // Invariant: a linked dependency directory is how this installation unifies a module
147
158
  // that would otherwise be present twice, and the link is made by A1 itself
148
159
  // at install and at every launch. Follow it to the directory it names and
149
160
  // collect from there, so the payload still reads only real files — but
@@ -0,0 +1,68 @@
1
+ import { PRODUCT_IDENTITY } from "../../product-identity.js";
2
+ import { type DependencyLayerReference } from "./dependency-layer.js";
3
+ import { type ImmutablePlatformPolicy } from "./immutable-platform.js";
4
+ import { type ReleaseFileIdentity } from "./release.js";
5
+ import { type CertifiedReleaseRecord, type MaterializedRelease } from "./release-store.js";
6
+ declare const RESTART_SEAL_VERSION = 1;
7
+ type EvidenceKind = "directory" | "file" | "binding";
8
+ interface PathEvidence {
9
+ readonly path: string;
10
+ readonly kind: EvidenceKind;
11
+ readonly device: string;
12
+ readonly inode: string;
13
+ readonly mode: number;
14
+ readonly size: string;
15
+ readonly modifiedNs: string;
16
+ readonly changedNs: string;
17
+ readonly bornNs: string;
18
+ }
19
+ interface LayerRestartEvidence extends DependencyLayerReference {
20
+ readonly layerRoot: PathEvidence;
21
+ readonly manifest: PathEvidence;
22
+ readonly certification: PathEvidence;
23
+ readonly bindingEvidence: PathEvidence;
24
+ readonly bindingTarget: string;
25
+ }
26
+ interface RestartSealCore {
27
+ readonly version: typeof RESTART_SEAL_VERSION;
28
+ readonly launchContract: string;
29
+ readonly platform: NodeJS.Platform;
30
+ readonly platformPolicy: ImmutablePlatformPolicy;
31
+ readonly releaseId: string;
32
+ readonly packageVersion: string;
33
+ readonly contentDigest: string;
34
+ readonly packageRoot: string;
35
+ readonly releaseRoot: PathEvidence;
36
+ readonly manifest: PathEvidence;
37
+ readonly launchEntries: readonly ReleaseFileIdentity[];
38
+ readonly launchEntryEvidence: readonly PathEvidence[];
39
+ readonly dependencyLayers: readonly LayerRestartEvidence[];
40
+ readonly certifiedAt: string;
41
+ }
42
+ export interface RestartSeal extends RestartSealCore {
43
+ readonly sealDigest: string;
44
+ }
45
+ interface ReleaseCertificationDocument {
46
+ readonly schema: typeof PRODUCT_IDENTITY.evidence.releaseCertificationSchema;
47
+ readonly releaseId: string;
48
+ readonly contentDigest: string;
49
+ readonly verifiedAt: string;
50
+ readonly checks: readonly {
51
+ readonly id: string;
52
+ readonly passed: boolean;
53
+ }[];
54
+ readonly restartSeal: RestartSeal | null;
55
+ }
56
+ export interface RestartValidationEvent {
57
+ readonly operation: "restart-evidence-read";
58
+ readonly path: string;
59
+ }
60
+ /** Build compact restart authority after complete content verification established read-only payload files. */
61
+ export declare function createRestartSeal(release: MaterializedRelease, dataDir: string): Promise<RestartSeal | null>;
62
+ /** Recover an approved release from durable bounded evidence without traversing its payload. */
63
+ export declare function readRestartCertifiedRelease(record: CertifiedReleaseRecord & {
64
+ readonly diagnosticsPath?: string | null;
65
+ }, dataDir: string, onEvent?: (event: RestartValidationEvent) => void): Promise<MaterializedRelease>;
66
+ export declare function releaseCertificationDocument(release: MaterializedRelease, restartSeal: RestartSeal | null, verifiedAt?: string): ReleaseCertificationDocument;
67
+ export declare function restartSealDigest(core: RestartSealCore): string;
68
+ export {};
@@ -0,0 +1,227 @@
1
+ import { createHash } from "node:crypto";
2
+ import { lstat, readFile, realpath, stat } from "node:fs/promises";
3
+ import { basename, isAbsolute, relative, resolve, sep } from "node:path";
4
+ import { PRODUCT_IDENTITY } from "../../product-identity.js";
5
+ import { PRIVATE_LAUNCH_CONTRACT, launchContractTarget } from "../launch-context/index.js";
6
+ import { DEPENDENCY_LAYER_MANIFEST, dependencyLayerCertificationPath, legacyDependencyLayerCertificationPath, readCertifiedDependencyLayer } from "./dependency-layer.js";
7
+ import { managedDependencyCertificationPath } from "./dependency-certification.js";
8
+ import { immutablePlatformPolicy } from "./immutable-platform.js";
9
+ import { PRODUCT_PACKAGE_NAME } from "./release.js";
10
+ import { RELEASE_MANIFEST_FILENAME } from "./release-store.js";
11
+ import { UpdateTransactionStore } from "./update-transaction.js";
12
+ const RESTART_SEAL_VERSION = 1;
13
+ const REQUIRED_LAUNCH_ENTRIES = ["bin/supervisor.js", "bin/guardian.js"];
14
+ /** Build compact restart authority after complete content verification established read-only payload files. */
15
+ export async function createRestartSeal(release, dataDir) {
16
+ const policy = immutablePlatformPolicy();
17
+ if (policy === null)
18
+ return null;
19
+ const canonicalData = await realpath(dataDir);
20
+ const releasesRoot = await realpath(resolve(canonicalData, "releases"));
21
+ const releaseRoot = await realpath(release.releaseRoot);
22
+ assertDirectChild(releasesRoot, releaseRoot, release.releaseId, "release");
23
+ const manifestPath = resolve(releaseRoot, RELEASE_MANIFEST_FILENAME);
24
+ const launchEntries = REQUIRED_LAUNCH_ENTRIES.map(path => release.files.find(candidate => candidate.path === path));
25
+ if (launchEntries.some(file => file === undefined))
26
+ return null;
27
+ const certifiedLaunchEntries = launchEntries;
28
+ const layersRoot = release.dependencyLayers?.length ? await realpath(resolve(canonicalData, "dependency-layers")) : null;
29
+ const dependencyLayers = await Promise.all((release.dependencyLayers ?? []).map(async (reference) => {
30
+ if (layersRoot === null)
31
+ throw new Error("restart certification has no dependency-layer root");
32
+ await readCertifiedDependencyLayer(canonicalData, reference.layerId, reference);
33
+ const layerRoot = await realpath(resolve(layersRoot, reference.layerId));
34
+ assertDirectChild(layersRoot, layerRoot, reference.layerId, "dependency layer");
35
+ const bindingPath = resolve(releaseRoot, reference.binding);
36
+ const bindingTarget = await realpath(bindingPath);
37
+ const expectedTarget = await realpath(resolve(layerRoot, "node_modules"));
38
+ if (bindingTarget !== expectedTarget)
39
+ throw new Error(`restart certification dependency binding targets unexpected content: ${bindingPath}`);
40
+ return {
41
+ ...reference,
42
+ layerRoot: await pathEvidence(layerRoot, "directory"),
43
+ manifest: await pathEvidence(resolve(layerRoot, DEPENDENCY_LAYER_MANIFEST), "file"),
44
+ certification: await pathEvidence(dependencyLayerCertificationPath(canonicalData, reference.layerId), "file"),
45
+ bindingEvidence: await pathEvidence(bindingPath, "binding", true),
46
+ bindingTarget,
47
+ };
48
+ }));
49
+ const core = {
50
+ version: RESTART_SEAL_VERSION,
51
+ launchContract: launchContractTarget(release),
52
+ platform: process.platform,
53
+ platformPolicy: policy,
54
+ releaseId: release.releaseId,
55
+ packageVersion: release.packageVersion,
56
+ contentDigest: release.contentDigest,
57
+ packageRoot: release.packageRoot,
58
+ releaseRoot: await pathEvidence(releaseRoot, "directory"),
59
+ manifest: await pathEvidence(manifestPath, "file"),
60
+ launchEntries: certifiedLaunchEntries,
61
+ launchEntryEvidence: await Promise.all(certifiedLaunchEntries.map(file => pathEvidence(resolve(releaseRoot, file.path), "file"))),
62
+ dependencyLayers,
63
+ certifiedAt: new Date().toISOString(),
64
+ };
65
+ return { ...core, sealDigest: restartSealDigest(core) };
66
+ }
67
+ /** Recover an approved release from durable bounded evidence without traversing its payload. */
68
+ export async function readRestartCertifiedRelease(record, dataDir, onEvent) {
69
+ const transaction = await new UpdateTransactionStore(dataDir).read();
70
+ if (transaction?.status === "active")
71
+ throw new Error("restart certification is unavailable during an active update transaction");
72
+ const certificationPath = resolve(dataDir, `certification-${record.releaseId}.json`);
73
+ if (record.diagnosticsPath !== undefined && record.diagnosticsPath !== certificationPath) {
74
+ throw new Error("restart certification path differs from the approved release record");
75
+ }
76
+ const certificationMetadata = await lstat(certificationPath);
77
+ onEvent?.({ operation: "restart-evidence-read", path: certificationPath });
78
+ if (!certificationMetadata.isFile() || certificationMetadata.isSymbolicLink() || (certificationMetadata.mode & 0o222) !== 0) {
79
+ throw new Error("restart certification is not an immutable regular file");
80
+ }
81
+ const certification = await readJson(certificationPath, onEvent);
82
+ if (certification.schema !== PRODUCT_IDENTITY.evidence.releaseCertificationSchema
83
+ || certification.releaseId !== record.releaseId || certification.contentDigest !== record.contentDigest
84
+ || !certification.checks.some(check => check.id === "immutable-content" && check.passed)) {
85
+ throw new Error("restart certification differs from the approved release record");
86
+ }
87
+ const seal = normalizeRestartSeal(certification.restartSeal);
88
+ // Invariant: a seal is restart authority only for a handoff this build can still
89
+ // perform, which is the contract it emits or the pre-cutover one it retains.
90
+ if (seal.launchContract !== PRIVATE_LAUNCH_CONTRACT && seal.launchContract !== "superseded") {
91
+ throw new Error(`restart seal declares an unsupported launch contract: ${String(seal.launchContract)}`);
92
+ }
93
+ if (seal.platform !== process.platform || seal.platformPolicy !== immutablePlatformPolicy()) {
94
+ throw new Error("restart certification platform immutability evidence is unsupported");
95
+ }
96
+ if (seal.releaseId !== record.releaseId || seal.contentDigest !== record.contentDigest
97
+ || resolve(seal.releaseRoot.path) !== resolve(record.releaseRoot)
98
+ || (record.packageVersion !== undefined && seal.packageVersion !== record.packageVersion)) {
99
+ throw new Error("restart seal differs from the approved release identity");
100
+ }
101
+ const { sealDigest, ...core } = seal;
102
+ if (restartSealDigest(core) !== sealDigest)
103
+ throw new Error("restart seal digest is invalid");
104
+ const canonicalData = await observedRealpath(dataDir, onEvent);
105
+ const releasesRoot = await observedRealpath(resolve(canonicalData, "releases"), onEvent);
106
+ const releaseRoot = await observedRealpath(seal.releaseRoot.path, onEvent);
107
+ assertDirectChild(releasesRoot, releaseRoot, seal.releaseId, "release");
108
+ await assertPathEvidence(seal.releaseRoot, onEvent);
109
+ await assertPathEvidence(seal.manifest, onEvent);
110
+ for (let index = 0; index < seal.launchEntries.length; index += 1) {
111
+ const file = seal.launchEntries[index];
112
+ if (!REQUIRED_LAUNCH_ENTRIES.includes(file.path)) {
113
+ throw new Error(`restart seal contains an unexpected launch entry: ${file.path}`);
114
+ }
115
+ const evidence = seal.launchEntryEvidence[index];
116
+ if (!evidence || evidence.path !== resolve(releaseRoot, file.path) || file.bytes !== Number(evidence.size)) {
117
+ throw new Error(`restart launch entry evidence differs: ${file.path}`);
118
+ }
119
+ await assertPathEvidence(evidence, onEvent);
120
+ }
121
+ if (seal.launchEntries.length !== REQUIRED_LAUNCH_ENTRIES.length)
122
+ throw new Error("restart seal launch entries are incomplete");
123
+ const layersRoot = seal.dependencyLayers.length ? await observedRealpath(resolve(canonicalData, "dependency-layers"), onEvent) : null;
124
+ for (const layer of seal.dependencyLayers) {
125
+ if (layersRoot === null)
126
+ throw new Error("restart seal has no dependency-layer root");
127
+ const layerRoot = await observedRealpath(layer.layerRoot.path, onEvent);
128
+ assertDirectChild(layersRoot, layerRoot, layer.layerId, "dependency layer");
129
+ await assertPathEvidence(layer.layerRoot, onEvent);
130
+ await assertPathEvidence(layer.manifest, onEvent);
131
+ const legacyPath = legacyDependencyLayerCertificationPath(canonicalData, layer.layerId);
132
+ const canonicalPath = dependencyLayerCertificationPath(canonicalData, layer.layerId);
133
+ if (layer.certification.path !== legacyPath && layer.certification.path !== canonicalPath) {
134
+ throw new Error("restart dependency certification path is outside managed storage");
135
+ }
136
+ await managedDependencyCertificationPath(canonicalData, layer.layerId, layer.certification.path === legacyPath);
137
+ await assertPathEvidence(layer.certification, onEvent);
138
+ await assertPathEvidence(layer.bindingEvidence, onEvent, true);
139
+ const bindingTarget = await observedRealpath(layer.bindingEvidence.path, onEvent);
140
+ const expectedTarget = await observedRealpath(resolve(layerRoot, "node_modules"), onEvent);
141
+ if (bindingTarget !== layer.bindingTarget || bindingTarget !== expectedTarget) {
142
+ throw new Error(`restart dependency binding targets unexpected content: ${layer.bindingEvidence.path}`);
143
+ }
144
+ }
145
+ return {
146
+ packageName: PRODUCT_PACKAGE_NAME,
147
+ launchContract: seal.launchContract,
148
+ packageVersion: seal.packageVersion,
149
+ contentDigest: seal.contentDigest,
150
+ releaseId: seal.releaseId,
151
+ packageRoot: seal.packageRoot,
152
+ files: seal.launchEntries,
153
+ ...(seal.dependencyLayers.length === 0 ? {} : {
154
+ dependencyLayers: seal.dependencyLayers.map(({ layerId, contentDigest, binding }) => ({ layerId, contentDigest, binding })),
155
+ }),
156
+ releaseRoot,
157
+ };
158
+ }
159
+ export function releaseCertificationDocument(release, restartSeal, verifiedAt = new Date().toISOString()) {
160
+ return {
161
+ schema: PRODUCT_IDENTITY.evidence.releaseCertificationSchema,
162
+ releaseId: release.releaseId,
163
+ contentDigest: release.contentDigest,
164
+ verifiedAt,
165
+ checks: [{ id: "immutable-content", passed: true }],
166
+ restartSeal,
167
+ };
168
+ }
169
+ export function restartSealDigest(core) {
170
+ return createHash("sha256").update(JSON.stringify(core)).digest("hex");
171
+ }
172
+ async function assertPathEvidence(evidence, onEvent, symbolic = false) {
173
+ const actual = await pathEvidence(evidence.path, evidence.kind, symbolic, onEvent);
174
+ if (JSON.stringify(actual) !== JSON.stringify(evidence))
175
+ throw new Error(`restart path evidence changed: ${evidence.path}`);
176
+ }
177
+ async function pathEvidence(path, kind, symbolic = false, onEvent) {
178
+ onEvent?.({ operation: "restart-evidence-read", path });
179
+ const metadata = symbolic ? await lstat(path, { bigint: true }) : await stat(path, { bigint: true });
180
+ if ((kind === "directory") !== metadata.isDirectory())
181
+ throw new Error(`restart evidence kind changed: ${path}`);
182
+ if (kind === "file" && !metadata.isFile())
183
+ throw new Error(`restart evidence file changed: ${path}`);
184
+ if (kind === "binding" && !metadata.isSymbolicLink())
185
+ throw new Error(`restart evidence binding changed: ${path}`);
186
+ if (kind === "file" && (metadata.mode & 146n) !== 0n)
187
+ throw new Error(`restart evidence file is writable: ${path}`);
188
+ return {
189
+ path: resolve(path),
190
+ kind,
191
+ device: metadata.dev.toString(),
192
+ inode: metadata.ino.toString(),
193
+ mode: Number(metadata.mode),
194
+ size: metadata.size.toString(),
195
+ modifiedNs: metadata.mtimeNs.toString(),
196
+ changedNs: metadata.ctimeNs.toString(),
197
+ bornNs: metadata.birthtimeNs.toString(),
198
+ };
199
+ }
200
+ function normalizeRestartSeal(value) {
201
+ if (!value || typeof value !== "object" || Array.isArray(value))
202
+ throw new Error("release certification has no durable restart seal");
203
+ const seal = value;
204
+ if (seal.version !== RESTART_SEAL_VERSION || typeof seal.platform !== "string" || typeof seal.platformPolicy !== "string"
205
+ || typeof seal.releaseId !== "string" || typeof seal.packageVersion !== "string" || typeof seal.contentDigest !== "string"
206
+ || typeof seal.packageRoot !== "string" || typeof seal.certifiedAt !== "string" || typeof seal.sealDigest !== "string"
207
+ || !seal.releaseRoot || !seal.manifest || !Array.isArray(seal.launchEntries) || !Array.isArray(seal.launchEntryEvidence)
208
+ || !Array.isArray(seal.dependencyLayers)) {
209
+ throw new Error("durable restart seal is invalid");
210
+ }
211
+ return seal;
212
+ }
213
+ async function readJson(path, onEvent) {
214
+ onEvent?.({ operation: "restart-evidence-read", path });
215
+ return JSON.parse(await readFile(path, "utf8"));
216
+ }
217
+ async function observedRealpath(path, onEvent) {
218
+ onEvent?.({ operation: "restart-evidence-read", path });
219
+ return await realpath(path);
220
+ }
221
+ function assertDirectChild(parent, child, expectedName, kind) {
222
+ const fromParent = relative(parent, child);
223
+ if (isAbsolute(fromParent) || fromParent === ".." || fromParent.startsWith(`..${sep}`) || fromParent.includes(sep)
224
+ || basename(child) !== expectedName) {
225
+ throw new Error(`restart ${kind} is outside its managed store: ${child}`);
226
+ }
227
+ }
@@ -0,0 +1,6 @@
1
+ import type { CohortState, ReleaseRecord } from "./cohort-state.js";
2
+ import type { UpdateTransaction } from "./update-transaction.js";
3
+ /** Keep interactive launches on the last successful release until the update commits success. */
4
+ export declare function selectUpdateLaunchRelease(state: CohortState, transaction: UpdateTransaction | null): ReleaseRecord | null;
5
+ /** Pause cohort retirement during preparation; afterward only the successful launch release admits new sessions. */
6
+ export declare function selectSupervisorLaunchReleaseId(state: CohortState, transaction: UpdateTransaction | null): string | null;
@@ -0,0 +1,17 @@
1
+ /** Keep interactive launches on the last successful release until the update commits success. */
2
+ export function selectUpdateLaunchRelease(state, transaction) {
3
+ if (transaction === null || transaction.status === "completed")
4
+ return null;
5
+ const prior = transaction.priorActiveReleaseId === null ? undefined : state.releases[transaction.priorActiveReleaseId];
6
+ if (!prior || prior.approval !== "approved") {
7
+ throw new Error("unfinished update has no verified previous release available for launch; resume the update");
8
+ }
9
+ return prior;
10
+ }
11
+ /** Pause cohort retirement during preparation; afterward only the successful launch release admits new sessions. */
12
+ export function selectSupervisorLaunchReleaseId(state, transaction) {
13
+ // Concurrency: both the previous cohort and the warming candidate must remain available until cutover.
14
+ if (transaction?.status === "active")
15
+ return null;
16
+ return selectUpdateLaunchRelease(state, transaction)?.releaseId ?? state.references.active;
17
+ }