@timurproko/a1 0.1.8-dev.235df0e → 0.1.8-dev.260

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 (485) hide show
  1. package/README.md +107 -67
  2. package/bin/cli.js +28 -10
  3. package/bin/guardian.js +8 -3
  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 +47 -20
  11. package/bin/warmup.js +27 -0
  12. package/dist/cli/capabilities.d.ts +6 -0
  13. package/dist/{src/cli → cli}/capabilities.js +1 -1
  14. package/dist/{src/cli → cli}/dispatch.d.ts +15 -1
  15. package/dist/cli/dispatch.js +261 -0
  16. package/dist/cli/package-messages.d.ts +26 -0
  17. package/dist/cli/package-messages.js +71 -0
  18. package/dist/{src/cli → cli}/packages.d.ts +11 -2
  19. package/dist/{src/cli → cli}/packages.js +24 -27
  20. package/dist/{src/cli → cli}/version-stats.d.ts +6 -0
  21. package/dist/cli/version-stats.js +112 -0
  22. package/dist/composition/agent-engine-bridge.d.ts +3 -0
  23. package/dist/composition/agent-engine-bridge.js +108 -0
  24. package/dist/composition/index.d.ts +3 -0
  25. package/dist/composition/index.js +3 -0
  26. package/dist/composition/owned-ui.d.ts +31 -0
  27. package/dist/composition/owned-ui.js +66 -0
  28. package/dist/composition/process.d.ts +16 -0
  29. package/dist/composition/process.js +45 -0
  30. package/dist/composition/settings-route-host.d.ts +8 -0
  31. package/dist/composition/settings-route-host.js +75 -0
  32. package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/capability-ports.d.ts +2 -2
  33. package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/domain-validation.js +22 -4
  34. package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/domain.d.ts +17 -0
  35. package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/package-ports.d.ts +6 -0
  36. package/dist/{src/foundation/owned-ui-contracts → contracts/owned-ui}/model.d.ts +36 -0
  37. package/dist/{src/foundation/owned-ui-contracts → contracts/owned-ui}/validation.js +25 -0
  38. package/dist/{src/features → features}/launch/development-launch.js +11 -3
  39. package/dist/{src/features → features}/launch/index.d.ts +0 -1
  40. package/dist/{src/features → features}/launch/index.js +0 -1
  41. package/dist/features/launch/intent.d.ts +10 -0
  42. package/dist/features/launch/intent.js +8 -0
  43. package/dist/{src/features → features}/launch/prepare-launch.d.ts +0 -2
  44. package/dist/{src/features → features}/launch/prepare-launch.js +2 -9
  45. package/dist/{src/features → features}/launch/profile-paths.d.ts +1 -2
  46. package/dist/{src/features → features}/launch/profile-paths.js +2 -8
  47. package/dist/{src/features → features}/launch/runtime-selection.d.ts +2 -5
  48. package/dist/{src/features → features}/owned-ui/customization.d.ts +3 -1
  49. package/dist/{src/features → features}/owned-ui/customization.js +3 -1
  50. package/dist/{src/features → features}/owned-ui/diagnostics.d.ts +2 -1
  51. package/dist/{src/features → features}/owned-ui/diagnostics.js +1 -0
  52. package/dist/{src/features → features}/owned-ui/index.d.ts +2 -0
  53. package/dist/{src/features → features}/owned-ui/index.js +2 -0
  54. package/dist/features/owned-ui/project-trust-prompt.d.ts +25 -0
  55. package/dist/features/owned-ui/project-trust-prompt.js +149 -0
  56. package/dist/{src/features → features}/owned-ui/run.d.ts +2 -2
  57. package/dist/{src/features → features}/owned-ui/run.js +2 -0
  58. package/dist/features/owned-ui/session-fork-prompt.d.ts +8 -0
  59. package/dist/features/owned-ui/session-fork-prompt.js +34 -0
  60. package/dist/{src/features → features}/owned-ui/settings-app.d.ts +3 -3
  61. package/dist/{src/features → features}/owned-ui/settings-app.js +103 -54
  62. package/dist/{src/features → features}/workspace/capabilities.d.ts +1 -1
  63. package/dist/{src/features → features}/workspace/reducer.d.ts +2 -1
  64. package/dist/{src/features → features}/workspace/reducer.js +2 -1
  65. package/dist/{src/features → features}/workspace/router.d.ts +2 -1
  66. package/dist/{src/features → features}/workspace/router.js +1 -0
  67. package/dist/{src/features → features}/workspace/store.d.ts +2 -1
  68. package/dist/{src/features → features}/workspace/store.js +1 -0
  69. package/dist/{src/foundation → foundation}/launch-guardian/main.d.ts +2 -0
  70. package/dist/{src/foundation → foundation}/launch-guardian/main.js +18 -5
  71. package/dist/{src/foundation → foundation}/lifecycle/index.d.ts +2 -0
  72. package/dist/{src/foundation → foundation}/lifecycle/index.js +2 -0
  73. package/dist/{src/foundation → foundation}/lifecycle/model.d.ts +1 -1
  74. package/dist/{src/foundation → foundation}/lifecycle/model.js +1 -1
  75. package/dist/foundation/lifecycle/paths.d.ts +30 -0
  76. package/dist/{src/foundation → foundation}/lifecycle/paths.js +29 -1
  77. package/dist/foundation/lifecycle/session-selection.d.ts +9 -0
  78. package/dist/foundation/lifecycle/session-selection.js +39 -0
  79. package/dist/foundation/lifecycle/supervisor-startup.d.ts +30 -0
  80. package/dist/foundation/lifecycle/supervisor-startup.js +106 -0
  81. package/dist/{src/foundation → foundation}/native-host-protocol/codec.d.ts +2 -0
  82. package/dist/{src/foundation → foundation}/native-host-protocol/codec.js +2 -0
  83. package/dist/{src/foundation → foundation}/native-host-protocol/messages.d.ts +1 -1
  84. package/dist/{src/foundation → foundation}/native-host-protocol/messages.js +1 -1
  85. package/dist/foundation/process-containment/darwin-process-inspector.d.ts +5 -0
  86. package/dist/foundation/process-containment/darwin-process-inspector.js +7 -0
  87. package/dist/{src/foundation → foundation}/process-containment/index.d.ts +1 -0
  88. package/dist/{src/foundation → foundation}/process-containment/index.js +1 -0
  89. package/dist/{src/foundation → foundation}/process-containment/linux-process-inspector.d.ts +1 -0
  90. package/dist/{src/foundation → foundation}/process-containment/linux-process-inspector.js +1 -0
  91. package/dist/{src/foundation → foundation}/process-containment/native-guardian-containment.d.ts +1 -0
  92. package/dist/{src/foundation → foundation}/process-containment/native-guardian-containment.js +1 -0
  93. package/dist/{src/foundation → foundation}/process-containment/windows-process-inspector.d.ts +3 -1
  94. package/dist/{src/foundation → foundation}/process-containment/windows-process-inspector.js +5 -2
  95. package/dist/{src/foundation → foundation}/protocol/client.d.ts +1 -0
  96. package/dist/{src/foundation → foundation}/protocol/client.js +1 -0
  97. package/dist/{src/foundation → foundation}/protocol/messages.d.ts +1 -0
  98. package/dist/{src/foundation → foundation}/protocol/messages.js +1 -0
  99. package/dist/{src/foundation → foundation}/release/bootstrap.d.ts +25 -6
  100. package/dist/{src/foundation → foundation}/release/bootstrap.js +124 -34
  101. package/dist/foundation/release/cohort-state.d.ts +156 -0
  102. package/dist/foundation/release/cohort-state.js +471 -0
  103. package/dist/foundation/release/dependency-layer.d.ts +82 -0
  104. package/dist/foundation/release/dependency-layer.js +497 -0
  105. package/dist/foundation/release/endpoints.d.ts +20 -0
  106. package/dist/foundation/release/endpoints.js +50 -0
  107. package/dist/foundation/release/immutable-platform.d.ts +6 -0
  108. package/dist/foundation/release/immutable-platform.js +13 -0
  109. package/dist/{src/foundation → foundation}/release/index.d.ts +4 -0
  110. package/dist/{src/foundation → foundation}/release/index.js +4 -0
  111. package/dist/foundation/release/release-gc.d.ts +71 -0
  112. package/dist/foundation/release/release-gc.js +734 -0
  113. package/dist/{src/foundation → foundation}/release/release-store.d.ts +7 -3
  114. package/dist/{src/foundation → foundation}/release/release-store.js +65 -13
  115. package/dist/{src/foundation → foundation}/release/release.d.ts +4 -1
  116. package/dist/{src/foundation → foundation}/release/release.js +10 -3
  117. package/dist/foundation/release/restart-certification.d.ts +67 -0
  118. package/dist/foundation/release/restart-certification.js +211 -0
  119. package/dist/{src/foundation → foundation}/release/update-transaction.d.ts +1 -0
  120. package/dist/{src/foundation → foundation}/release/update-transaction.js +1 -0
  121. package/dist/{src/foundation → foundation}/release/update.d.ts +19 -3
  122. package/dist/{src/foundation → foundation}/release/update.js +116 -56
  123. package/dist/foundation/release/warmup.d.ts +3 -0
  124. package/dist/foundation/release/warmup.js +35 -0
  125. package/dist/foundation/startup/index.d.ts +1 -0
  126. package/dist/foundation/startup/index.js +1 -0
  127. package/dist/foundation/startup/startup-runtime.d.ts +36 -0
  128. package/dist/foundation/startup/startup-runtime.js +140 -0
  129. package/dist/{src/foundation → foundation}/storage/control-store.d.ts +2 -1
  130. package/dist/{src/foundation → foundation}/storage/control-store.js +39 -4
  131. package/dist/{src/foundation → foundation}/structured-agent-runtime/backpressure.d.ts +2 -1
  132. package/dist/{src/foundation → foundation}/structured-agent-runtime/backpressure.js +2 -1
  133. package/dist/{src/foundation → foundation}/structured-agent-runtime/commands.d.ts +2 -1
  134. package/dist/{src/foundation → foundation}/structured-agent-runtime/commands.js +2 -1
  135. package/dist/{src/foundation → foundation}/structured-agent-runtime/handshake.d.ts +1 -1
  136. package/dist/{src/foundation → foundation}/structured-agent-runtime/handshake.js +1 -1
  137. package/dist/{src/foundation → foundation}/structured-agent-runtime/reconnection.d.ts +2 -1
  138. package/dist/{src/foundation → foundation}/structured-agent-runtime/reconnection.js +2 -1
  139. package/dist/{src/foundation → foundation}/structured-agent-runtime/state.d.ts +2 -1
  140. package/dist/{src/foundation → foundation}/structured-agent-runtime/state.js +2 -1
  141. package/dist/foundation/supervision/index.d.ts +3 -0
  142. package/dist/foundation/supervision/index.js +3 -0
  143. package/dist/foundation/supervision/main.d.ts +1 -0
  144. package/dist/foundation/supervision/main.js +80 -0
  145. package/dist/foundation/supervision/paths.d.ts +1 -0
  146. package/dist/foundation/supervision/paths.js +1 -0
  147. package/dist/{src/foundation → foundation}/supervision/server.d.ts +19 -1
  148. package/dist/{src/foundation → foundation}/supervision/server.js +65 -3
  149. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/components.d.ts +1 -1
  150. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/conformance.d.ts +1 -0
  151. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/conformance.js +3 -2
  152. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/index.d.ts +1 -1
  153. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/index.js +1 -1
  154. package/dist/integrations/pi/components/owned-editor-ux.d.ts +55 -0
  155. package/dist/integrations/pi/components/owned-editor-ux.js +778 -0
  156. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-components.d.ts +1 -0
  157. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-components.js +1 -0
  158. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-editor-autocomplete.js +54 -6
  159. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-extension-ui.d.ts +1 -1
  160. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-footer-status.d.ts +3 -3
  161. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-footer-status.js +49 -18
  162. package/dist/integrations/pi/components/shell-presenters-info.d.ts +36 -0
  163. package/dist/integrations/pi/components/shell-presenters-info.js +78 -0
  164. package/dist/integrations/pi/components/shell-presenters-transcript.d.ts +25 -0
  165. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-presenters-transcript.js +92 -131
  166. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-selectors-dialogs.d.ts +5 -2
  167. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-selectors-dialogs.js +2 -1
  168. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-shared-facade.d.ts +57 -8
  169. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-shared-facade.js +4 -2
  170. package/dist/integrations/pi/components/submitted-prompt-adapter.d.ts +13 -0
  171. package/dist/integrations/pi/components/submitted-prompt-adapter.js +27 -0
  172. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/adjacent/core/keybindings.d.ts +10 -2
  173. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/adjacent/core/keybindings.js +36 -3
  174. package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/session-footer.d.ts +1 -1
  175. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/adapter.d.ts +28 -4
  176. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/adapter.js +714 -127
  177. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/conformance.d.ts +2 -0
  178. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/conformance.js +4 -2
  179. package/dist/integrations/pi/engine/http-dispatcher.d.ts +4 -0
  180. package/dist/integrations/pi/engine/http-dispatcher.js +25 -0
  181. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/index.d.ts +4 -0
  182. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/index.js +4 -0
  183. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/model-auth-integration.d.ts +2 -1
  184. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/model-auth-integration.js +1 -0
  185. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/package-integration.d.ts +1 -1
  186. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/package-integration.js +32 -26
  187. package/dist/integrations/pi/engine/project-trust-preflight.d.ts +22 -0
  188. package/dist/integrations/pi/engine/project-trust-preflight.js +50 -0
  189. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/resource-extension-integration.d.ts +2 -1
  190. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/resource-extension-integration.js +1 -0
  191. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/runtime-integration.d.ts +19 -1
  192. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/runtime-integration.js +47 -5
  193. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/session-integration.d.ts +4 -2
  194. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/session-integration.js +19 -4
  195. package/dist/integrations/pi/engine/session-selection.d.ts +28 -0
  196. package/dist/integrations/pi/engine/session-selection.js +90 -0
  197. package/dist/integrations/pi/engine/settings-effects.d.ts +66 -0
  198. package/dist/integrations/pi/engine/settings-effects.js +249 -0
  199. package/dist/integrations/pi/engine/settings-integration.d.ts +43 -0
  200. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/settings-integration.js +102 -108
  201. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/workflow-controllers.d.ts +3 -2
  202. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/workflow-controllers.js +1 -0
  203. package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/workflows.d.ts +18 -1
  204. package/dist/integrations/pi/session-ui/clipboard-image.d.ts +11 -0
  205. package/dist/integrations/pi/session-ui/clipboard-image.js +29 -0
  206. package/dist/{src/foundation/pi-owned-ui-integration → integrations/pi/session-ui}/index.d.ts +1 -0
  207. package/dist/{src/foundation/pi-owned-ui-integration → integrations/pi/session-ui}/index.js +1 -0
  208. package/dist/integrations/pi/session-ui/prompt-chips.d.ts +23 -0
  209. package/dist/integrations/pi/session-ui/prompt-chips.js +246 -0
  210. package/dist/integrations/pi/session-ui/route-host.d.ts +5 -0
  211. package/dist/integrations/pi/session-ui/session-shell-root.d.ts +141 -0
  212. package/dist/integrations/pi/session-ui/session-shell-root.js +1158 -0
  213. package/dist/integrations/pi/session-ui/session-shell.d.ts +55 -0
  214. package/dist/{src/foundation/pi-owned-ui-integration → integrations/pi/session-ui}/session-shell.js +479 -719
  215. package/dist/integrations/pi/session-ui/session-viewport-controller.d.ts +45 -0
  216. package/dist/integrations/pi/session-ui/session-viewport-controller.js +463 -0
  217. package/dist/integrations/pi/session-ui/stream-presentation-coalescer.d.ts +29 -0
  218. package/dist/integrations/pi/session-ui/stream-presentation-coalescer.js +79 -0
  219. package/dist/integrations/pi/session-ui/system-clipboard.d.ts +20 -0
  220. package/dist/integrations/pi/session-ui/system-clipboard.js +130 -0
  221. package/dist/{src/foundation/pi-tui-runtime-adapter → integrations/pi/tui-runtime}/adapter.d.ts +8 -1
  222. package/dist/{src/foundation/pi-tui-runtime-adapter → integrations/pi/tui-runtime}/adapter.js +216 -9
  223. package/dist/{src/foundation/pi-tui-runtime-adapter → integrations/pi/tui-runtime}/contracts.d.ts +29 -6
  224. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +74 -0
  225. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +380 -0
  226. package/dist/{src/foundation/pi-tui-runtime-adapter → integrations/pi/tui-runtime}/index.d.ts +2 -0
  227. package/dist/{src/foundation/pi-tui-runtime-adapter → integrations/pi/tui-runtime}/index.js +2 -0
  228. package/dist/integrations/pi/tui-runtime/input-presentation-coordinator.d.ts +39 -0
  229. package/dist/integrations/pi/tui-runtime/input-presentation-coordinator.js +139 -0
  230. package/dist/{src/foundation/pi-tui-runtime-adapter → integrations/pi/tui-runtime}/presentation-adapter.d.ts +1 -1
  231. package/dist/native/darwin-arm64/manifest.json +4 -4
  232. package/dist/native/darwin-arm64/process-guardian +0 -0
  233. package/dist/native/linux-x64/manifest.json +3 -3
  234. package/dist/native/linux-x64/process-guardian +0 -0
  235. package/dist/native/win32-x64/manifest.json +3 -3
  236. package/dist/native/win32-x64/process-guardian.exe +0 -0
  237. package/dist/{src/product-identity.d.ts → product-identity.d.ts} +3 -3
  238. package/dist/{src/product-identity.js → product-identity.js} +7 -5
  239. package/dist/{src/product-identity.json → product-identity.json} +11 -6
  240. package/dist/runtime-payload-inventory.json +122328 -0
  241. package/dist/{src/foundation/ui-apps → ui/apps}/contracts.d.ts +23 -1
  242. package/dist/{src/foundation/ui-apps → ui/apps}/host.d.ts +1 -1
  243. package/dist/{src/foundation/ui-apps → ui/apps}/host.js +14 -10
  244. package/dist/{src/foundation/ui-apps → ui/apps}/registry.d.ts +1 -0
  245. package/dist/{src/foundation/ui-apps → ui/apps}/registry.js +1 -0
  246. package/dist/{src/foundation/ui-components → ui/components}/dialog-panel.js +5 -3
  247. package/dist/{src/foundation/ui-components → ui/components}/frame.d.ts +1 -0
  248. package/dist/{src/foundation/ui-components → ui/components}/frame.js +1 -0
  249. package/dist/{src/foundation/ui-components → ui/components}/index.d.ts +5 -0
  250. package/dist/{src/foundation/ui-components → ui/components}/index.js +5 -0
  251. package/dist/{src/foundation/ui-components → ui/components}/line-input.d.ts +1 -6
  252. package/dist/{src/foundation/ui-components → ui/components}/line-input.js +4 -9
  253. package/dist/{src/foundation/ui-components → ui/components}/list-view.d.ts +0 -6
  254. package/dist/{src/foundation/ui-components → ui/components}/list-view.js +14 -7
  255. package/dist/{src/foundation/ui-components → ui/components}/mouse.d.ts +10 -0
  256. package/dist/{src/foundation/ui-components → ui/components}/mouse.js +23 -0
  257. package/dist/ui/components/progress-status.d.ts +2 -0
  258. package/dist/ui/components/progress-status.js +4 -0
  259. package/dist/ui/components/prompt-row.d.ts +14 -0
  260. package/dist/ui/components/prompt-row.js +20 -0
  261. package/dist/{src/foundation/ui-components → ui/components}/scrollbar.d.ts +26 -0
  262. package/dist/{src/foundation/ui-components → ui/components}/scrollbar.js +35 -0
  263. package/dist/{src/foundation/ui-components → ui/components}/shortcuts.d.ts +1 -0
  264. package/dist/{src/foundation/ui-components → ui/components}/shortcuts.js +1 -0
  265. package/dist/ui/components/spans.d.ts +25 -0
  266. package/dist/ui/components/spans.js +257 -0
  267. package/dist/ui/components/submitted-prompt.d.ts +23 -0
  268. package/dist/ui/components/submitted-prompt.js +50 -0
  269. package/dist/{src/foundation/ui-components → ui/components}/surface.d.ts +0 -5
  270. package/dist/{src/foundation/ui-components → ui/components}/surface.js +1 -5
  271. package/dist/ui/components/text-selection.d.ts +62 -0
  272. package/dist/ui/components/text-selection.js +208 -0
  273. package/dist/{src/foundation/ui-components → ui/components}/text.d.ts +14 -0
  274. package/dist/{src/foundation/ui-components → ui/components}/text.js +66 -4
  275. package/dist/ui/components/transcript-viewport.d.ts +152 -0
  276. package/dist/ui/components/transcript-viewport.js +631 -0
  277. package/dist/ui/components/visible-hyperlinks.d.ts +19 -0
  278. package/dist/ui/components/visible-hyperlinks.js +64 -0
  279. package/dist/{src/foundation/owned-ui-settings → ui/settings}/declarations.d.ts +8 -1
  280. package/dist/{src/foundation/owned-ui-settings → ui/settings}/declarations.js +33 -5
  281. package/dist/{src/foundation/owned-ui-settings → ui/settings}/migrations.d.ts +1 -1
  282. package/dist/{src/foundation/owned-ui-settings → ui/settings}/migrations.js +21 -2
  283. package/dist/{src/foundation/owned-ui-settings → ui/settings}/sections.d.ts +6 -19
  284. package/dist/{src/foundation/owned-ui-settings → ui/settings}/sections.js +32 -23
  285. package/dist/{src/foundation/owned-ui-settings → ui/settings}/session.d.ts +9 -17
  286. package/dist/{src/foundation/owned-ui-settings → ui/settings}/session.js +65 -55
  287. package/dist/{src/foundation/owned-ui-settings → ui/settings}/store.d.ts +1 -0
  288. package/dist/{src/foundation/owned-ui-settings → ui/settings}/store.js +2 -1
  289. package/docs/architecture/boundaries.md +9 -9
  290. package/docs/architecture/code-documentation.md +77 -0
  291. package/docs/architecture/process-guardian-provenance.md +3 -1
  292. package/docs/architecture/project-structure.md +67 -30
  293. package/docs/architecture/resource-and-data-policy.md +1 -1
  294. package/docs/architecture/toolchain.md +10 -10
  295. package/docs/architecture/ui-reference-provenance.md +36 -5
  296. package/docs/ci-release-runbook.md +186 -79
  297. package/docs/features/launch-profiles.md +24 -17
  298. package/docs/manual-ghost-link-baseline.md +89 -0
  299. package/docs/manual-launch-instance-acceptance.md +12 -35
  300. package/docs/manual-owned-ui-checkpoint.md +78 -0
  301. package/docs/manual-pi-boundary-candidate.md +4 -5
  302. package/docs/manual-terminal-colour-check.md +4 -3
  303. package/docs/repository-governance-live-acceptance.md +77 -0
  304. package/package.json +37 -27
  305. package/dist/src/cli/capabilities.d.ts +0 -15
  306. package/dist/src/cli/dispatch.js +0 -177
  307. package/dist/src/cli/version-stats.js +0 -72
  308. package/dist/src/composition/index.d.ts +0 -48
  309. package/dist/src/composition/index.js +0 -258
  310. package/dist/src/features/launch/intent.d.ts +0 -7
  311. package/dist/src/features/launch/intent.js +0 -4
  312. package/dist/src/features/launch/profiles.d.ts +0 -12
  313. package/dist/src/features/launch/profiles.js +0 -26
  314. package/dist/src/foundation/lifecycle/paths.d.ts +0 -10
  315. package/dist/src/foundation/pi-component-adapter/shell-presenters-transcript.d.ts +0 -57
  316. package/dist/src/foundation/pi-engine-adapter/settings-integration.d.ts +0 -55
  317. package/dist/src/foundation/pi-owned-ui-integration/route-host.d.ts +0 -29
  318. package/dist/src/foundation/pi-owned-ui-integration/session-shell.d.ts +0 -106
  319. package/dist/src/foundation/release/cohort-state.d.ts +0 -70
  320. package/dist/src/foundation/release/cohort-state.js +0 -202
  321. package/dist/src/foundation/release/release-gc.d.ts +0 -5
  322. package/dist/src/foundation/release/release-gc.js +0 -16
  323. package/dist/src/foundation/supervision/index.d.ts +0 -3
  324. package/dist/src/foundation/supervision/index.js +0 -3
  325. package/dist/src/foundation/supervision/main.d.ts +0 -1
  326. package/dist/src/foundation/supervision/main.js +0 -41
  327. package/dist/src/foundation/supervision/paths.d.ts +0 -1
  328. package/dist/src/foundation/supervision/paths.js +0 -1
  329. package/dist/src/foundation/ui-components/spans.d.ts +0 -7
  330. package/dist/src/foundation/ui-components/spans.js +0 -59
  331. package/docs/manual-transparent-checkpoint.md +0 -53
  332. /package/dist/{src/cli → cli}/index.d.ts +0 -0
  333. /package/dist/{src/cli → cli}/index.js +0 -0
  334. /package/dist/{src/cli → cli}/version.d.ts +0 -0
  335. /package/dist/{src/cli → cli}/version.js +0 -0
  336. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/capability-ports.js +0 -0
  337. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/domain-validation.d.ts +0 -0
  338. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/domain.js +0 -0
  339. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/index.d.ts +0 -0
  340. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/index.js +0 -0
  341. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/model.d.ts +0 -0
  342. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/model.js +0 -0
  343. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/package-ports.js +0 -0
  344. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/ports.d.ts +0 -0
  345. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/ports.js +0 -0
  346. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/serialization.d.ts +0 -0
  347. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/serialization.js +0 -0
  348. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/validation.d.ts +0 -0
  349. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/validation.js +0 -0
  350. /package/dist/{src/foundation/owned-ui-contracts → contracts/owned-ui}/extension-ui.d.ts +0 -0
  351. /package/dist/{src/foundation/owned-ui-contracts → contracts/owned-ui}/extension-ui.js +0 -0
  352. /package/dist/{src/foundation/owned-ui-contracts → contracts/owned-ui}/index.d.ts +0 -0
  353. /package/dist/{src/foundation/owned-ui-contracts → contracts/owned-ui}/index.js +0 -0
  354. /package/dist/{src/foundation/owned-ui-contracts → contracts/owned-ui}/model.js +0 -0
  355. /package/dist/{src/foundation/owned-ui-contracts → contracts/owned-ui}/validation.d.ts +0 -0
  356. /package/dist/{src/foundation/presentation-contracts → contracts/presentation}/index.d.ts +0 -0
  357. /package/dist/{src/foundation/presentation-contracts → contracts/presentation}/index.js +0 -0
  358. /package/dist/{src/foundation/workspace-contracts → contracts/workspace}/index.d.ts +0 -0
  359. /package/dist/{src/foundation/workspace-contracts → contracts/workspace}/index.js +0 -0
  360. /package/dist/{src/foundation/workspace-contracts → contracts/workspace}/model.d.ts +0 -0
  361. /package/dist/{src/foundation/workspace-contracts → contracts/workspace}/model.js +0 -0
  362. /package/dist/{src/foundation/workspace-contracts → contracts/workspace}/validation.d.ts +0 -0
  363. /package/dist/{src/foundation/workspace-contracts → contracts/workspace}/validation.js +0 -0
  364. /package/dist/{src/features → features}/launch/development-launch.d.ts +0 -0
  365. /package/dist/{src/features → features}/launch/initialize-profile.d.ts +0 -0
  366. /package/dist/{src/features → features}/launch/initialize-profile.js +0 -0
  367. /package/dist/{src/features → features}/launch/runtime-selection.js +0 -0
  368. /package/dist/{src/features → features}/workspace/capabilities.js +0 -0
  369. /package/dist/{src/features → features}/workspace/index.d.ts +0 -0
  370. /package/dist/{src/features → features}/workspace/index.js +0 -0
  371. /package/dist/{src/features → features}/workspace/presentation.d.ts +0 -0
  372. /package/dist/{src/features → features}/workspace/presentation.js +0 -0
  373. /package/dist/{src/features → features}/workspace/reconciliation.d.ts +0 -0
  374. /package/dist/{src/features → features}/workspace/reconciliation.js +0 -0
  375. /package/dist/{src/foundation → foundation}/launch-guardian/index.d.ts +0 -0
  376. /package/dist/{src/foundation → foundation}/launch-guardian/index.js +0 -0
  377. /package/dist/{src/foundation → foundation}/lifecycle/commands.d.ts +0 -0
  378. /package/dist/{src/foundation → foundation}/lifecycle/commands.js +0 -0
  379. /package/dist/{src/foundation → foundation}/lifecycle/launch-instance.d.ts +0 -0
  380. /package/dist/{src/foundation → foundation}/lifecycle/launch-instance.js +0 -0
  381. /package/dist/{src/foundation → foundation}/native-host-protocol/evidence.d.ts +0 -0
  382. /package/dist/{src/foundation → foundation}/native-host-protocol/evidence.js +0 -0
  383. /package/dist/{src/foundation → foundation}/native-host-protocol/index.d.ts +0 -0
  384. /package/dist/{src/foundation → foundation}/native-host-protocol/index.js +0 -0
  385. /package/dist/{src/foundation → foundation}/native-host-protocol/proof-gate.d.ts +0 -0
  386. /package/dist/{src/foundation → foundation}/native-host-protocol/proof-gate.js +0 -0
  387. /package/dist/{src/foundation → foundation}/process-containment/artifact.d.ts +0 -0
  388. /package/dist/{src/foundation → foundation}/process-containment/artifact.js +0 -0
  389. /package/dist/{src/foundation → foundation}/process-containment/contracts.d.ts +0 -0
  390. /package/dist/{src/foundation → foundation}/process-containment/contracts.js +0 -0
  391. /package/dist/{src/foundation → foundation}/protocol/index.d.ts +0 -0
  392. /package/dist/{src/foundation → foundation}/protocol/index.js +0 -0
  393. /package/dist/{src/foundation → foundation}/release/cohort-selection.d.ts +0 -0
  394. /package/dist/{src/foundation → foundation}/release/cohort-selection.js +0 -0
  395. /package/dist/{src/foundation → foundation}/release/concurrency.d.ts +0 -0
  396. /package/dist/{src/foundation → foundation}/release/concurrency.js +0 -0
  397. /package/dist/{src/foundation → foundation}/release/process-cleanup.d.ts +0 -0
  398. /package/dist/{src/foundation → foundation}/release/process-cleanup.js +0 -0
  399. /package/dist/{src/foundation → foundation}/release/stable-release.d.ts +0 -0
  400. /package/dist/{src/foundation → foundation}/release/stable-release.js +0 -0
  401. /package/dist/{src/foundation → foundation}/storage/index.d.ts +0 -0
  402. /package/dist/{src/foundation → foundation}/storage/index.js +0 -0
  403. /package/dist/{src/foundation → foundation}/structured-agent-runtime/index.d.ts +0 -0
  404. /package/dist/{src/foundation → foundation}/structured-agent-runtime/index.js +0 -0
  405. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/components.js +0 -0
  406. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/resources/builtin-themes.d.ts +0 -0
  407. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/resources/builtin-themes.js +0 -0
  408. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-editor-autocomplete.d.ts +0 -0
  409. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-extension-ui.js +0 -0
  410. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/theme.d.ts +0 -0
  411. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/theme.js +0 -0
  412. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/countdown-timer.d.ts +0 -0
  413. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/countdown-timer.js +0 -0
  414. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/custom-entry.d.ts +0 -0
  415. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/custom-entry.js +0 -0
  416. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/daxnuts.d.ts +0 -0
  417. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/daxnuts.js +0 -0
  418. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/earendil-announcement.d.ts +0 -0
  419. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/earendil-announcement.js +0 -0
  420. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/extension-editor.d.ts +0 -0
  421. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/extension-editor.js +0 -0
  422. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/first-time-setup.d.ts +0 -0
  423. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/first-time-setup.js +0 -0
  424. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/markdown-transform.d.ts +0 -0
  425. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/markdown-transform.js +0 -0
  426. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/mermaid.d.ts +0 -0
  427. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/mermaid.js +0 -0
  428. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/owned-editor.d.ts +0 -0
  429. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/owned-editor.js +0 -0
  430. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/scoped-models-selector.d.ts +0 -0
  431. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/scoped-models-selector.js +0 -0
  432. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/session-footer.js +0 -0
  433. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/session-selector-search.d.ts +0 -0
  434. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/session-selector-search.js +0 -0
  435. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/session-selector.d.ts +0 -0
  436. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/session-selector.js +0 -0
  437. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/skill-invocation-message.d.ts +0 -0
  438. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/skill-invocation-message.js +0 -0
  439. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/status-indicator.d.ts +0 -0
  440. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/status-indicator.js +0 -0
  441. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/tree-selector.d.ts +0 -0
  442. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/tree-selector.js +0 -0
  443. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/trust-selector.d.ts +0 -0
  444. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/trust-selector.js +0 -0
  445. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/external-editor.d.ts +0 -0
  446. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/external-editor.js +0 -0
  447. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/model-search.d.ts +0 -0
  448. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/model-search.js +0 -0
  449. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/theme/theme-controller.d.ts +0 -0
  450. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/theme/theme-controller.js +0 -0
  451. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/theme/theme.d.ts +0 -0
  452. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/theme/theme.js +0 -0
  453. /package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/pi-settings-metadata.json +0 -0
  454. /package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/public-main-entry.d.ts +0 -0
  455. /package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/public-main-entry.js +0 -0
  456. /package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/workflows.js +0 -0
  457. /package/dist/{src/foundation/pi-owned-ui-integration → integrations/pi/session-ui}/route-host.js +0 -0
  458. /package/dist/{src/foundation/pi-tui-runtime-adapter → integrations/pi/tui-runtime}/conformance.d.ts +0 -0
  459. /package/dist/{src/foundation/pi-tui-runtime-adapter → integrations/pi/tui-runtime}/conformance.js +0 -0
  460. /package/dist/{src/foundation/pi-tui-runtime-adapter → integrations/pi/tui-runtime}/contracts.js +0 -0
  461. /package/dist/{src/foundation/pi-tui-runtime-adapter → integrations/pi/tui-runtime}/presentation-adapter.js +0 -0
  462. /package/dist/{src/foundation/ui-apps → ui/apps}/contracts.js +0 -0
  463. /package/dist/{src/foundation/ui-apps → ui/apps}/index.d.ts +0 -0
  464. /package/dist/{src/foundation/ui-apps → ui/apps}/index.js +0 -0
  465. /package/dist/{src/foundation/ui-components → ui/components}/dialog-panel.d.ts +0 -0
  466. /package/dist/{src/foundation/ui-components → ui/components}/label.d.ts +0 -0
  467. /package/dist/{src/foundation/ui-components → ui/components}/label.js +0 -0
  468. /package/dist/{src/foundation/ui-components → ui/components}/list-block.d.ts +0 -0
  469. /package/dist/{src/foundation/ui-components → ui/components}/list-block.js +0 -0
  470. /package/dist/{src/foundation/ui-components → ui/components}/pane.d.ts +0 -0
  471. /package/dist/{src/foundation/ui-components → ui/components}/pane.js +0 -0
  472. /package/dist/{src/foundation/ui-components → ui/components}/revision.d.ts +0 -0
  473. /package/dist/{src/foundation/ui-components → ui/components}/revision.js +0 -0
  474. /package/dist/{src/foundation/ui-components → ui/components}/status-line.d.ts +0 -0
  475. /package/dist/{src/foundation/ui-components → ui/components}/status-line.js +0 -0
  476. /package/dist/{src/foundation/ui-components → ui/components}/stepper.d.ts +0 -0
  477. /package/dist/{src/foundation/ui-components → ui/components}/stepper.js +0 -0
  478. /package/dist/{src/foundation/ui-components → ui/components}/theme.d.ts +0 -0
  479. /package/dist/{src/foundation/ui-components → ui/components}/theme.js +0 -0
  480. /package/dist/{src/foundation/ui-components → ui/components}/value-menu.d.ts +0 -0
  481. /package/dist/{src/foundation/ui-components → ui/components}/value-menu.js +0 -0
  482. /package/dist/{src/foundation/owned-ui-settings → ui/settings}/index.d.ts +0 -0
  483. /package/dist/{src/foundation/owned-ui-settings → ui/settings}/index.js +0 -0
  484. /package/dist/{src/foundation/owned-ui-settings → ui/settings}/resolution.d.ts +0 -0
  485. /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
  }
@@ -27,17 +29,19 @@ export interface CertifiedReleaseRecord {
27
29
  readonly packageVersion?: string;
28
30
  readonly contentDigest: string;
29
31
  }
32
+ /** Process-authority compatibility controls for metadata-only release loading. */
33
+ export type ReadCertifiedReleaseManifestOptions = ReadCertifiedDependencyLayerOptions;
30
34
  export declare function materializeRelease(packageRoot: string, dataDir: string, options?: MaterializeReleaseOptions): Promise<MaterializedRelease>;
31
35
  /** Consume proof that this exact object was freshly materialized or fully verified in this process. */
32
36
  export declare function consumeMaterializationProof(release: MaterializedRelease): boolean;
33
- export declare function readMaterializedRelease(releaseRoot: string): Promise<MaterializedRelease>;
37
+ export declare function readMaterializedRelease(releaseRoot: string, selectedStoreRoot?: string): Promise<MaterializedRelease>;
34
38
  /**
35
39
  * Load metadata for a release whose bytes were already certified by the
36
40
  * current parent process or an authenticated live supervisor. Callers must
37
41
  * establish one of those preconditions; untrusted releases require full
38
42
  * verification.
39
43
  */
40
- export declare function readCertifiedReleaseManifest(record: CertifiedReleaseRecord, selectedStoreRoot: string): Promise<MaterializedRelease>;
44
+ export declare function readCertifiedReleaseManifest(record: CertifiedReleaseRecord, selectedStoreRoot: string, options?: ReadCertifiedReleaseManifestOptions): Promise<MaterializedRelease>;
41
45
  export declare function verifyMaterializedRelease(releaseRoot: string, expected?: ReleaseIdentity, selectedStoreRoot?: string, options?: VerifyMaterializedReleaseOptions): Promise<MaterializedRelease>;
42
46
  export declare function assertImmutableExecutionRoot(release: MaterializedRelease, dataDir: string): Promise<void>;
43
47
  export declare function resolveReleaseEntryPoint(release: MaterializedRelease, entryPoint: string): Promise<string>;
@@ -1,9 +1,11 @@
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
6
  import { mapWithConcurrency } from "./concurrency.js";
7
+ import { assertImmutableFileMode } from "./immutable-platform.js";
8
+ import { dependencyReference, materializeDependencyLayer, readCertifiedDependencyLayer, selectPublishedDependencyRuntimePayload, verifyDependencyLayer, } from "./dependency-layer.js";
7
9
  const RELEASE_FILE_IO_CONCURRENCY = 32;
8
10
  const certificationReady = new WeakSet();
9
11
  export const RELEASE_MANIFEST_FILENAME = PRODUCT_IDENTITY.manifest.releaseFilename;
@@ -13,15 +15,32 @@ export async function materializeRelease(packageRoot, dataDir, options = {}) {
13
15
  });
14
16
  const storeRoot = resolve(dataDir, "releases");
15
17
  await mkdir(storeRoot, { recursive: true, mode: 0o700 });
16
- options.onProgress?.({ phase: "copying", fileCount: payload.paths.length });
18
+ const dependencyPaths = payload.paths.filter(path => path.startsWith("node_modules/"));
19
+ const productPaths = payload.paths.filter(path => !path.startsWith("node_modules/"));
20
+ const selectedDependencies = await selectPublishedDependencyRuntimePayload(payload.packageRoot, dependencyPaths);
21
+ options.onRuntimeInventory?.(selectedDependencies.inventory);
22
+ const layerOperations = [];
23
+ const layer = await materializeDependencyLayer(payload.packageRoot, dataDir, selectedDependencies.paths, {
24
+ inventory: selectedDependencies.inventory,
25
+ cachedFiles: payload.cachedFiles,
26
+ onOperation: event => layerOperations.push(event),
27
+ ...(options.writeCandidateFile === undefined ? {} : { writeCandidateFile: options.writeCandidateFile }),
28
+ });
29
+ const layerReferences = layer === null ? [] : [dependencyReference(layer)];
30
+ options.onProgress?.({
31
+ phase: "copying",
32
+ fileCount: productPaths.length + (layer?.reused === false ? layer.files.length : 0),
33
+ });
34
+ for (const event of layerOperations)
35
+ options.onOperation?.(event);
17
36
  const candidate = resolveWithin(storeRoot, `.candidate-${randomUUID()}`);
18
37
  await mkdir(candidate, { recursive: false, mode: 0o700 });
19
38
  try {
20
- const directories = [...new Set(payload.paths.map(path => dirname(resolveWithin(candidate, path))))];
39
+ const directories = [...new Set(productPaths.map(path => dirname(resolveWithin(candidate, path))))];
21
40
  await mapWithConcurrency(directories, RELEASE_FILE_IO_CONCURRENCY, async (directory) => {
22
41
  await mkdir(directory, { recursive: true, mode: 0o700 });
23
42
  });
24
- const files = await mapWithConcurrency(payload.paths, RELEASE_FILE_IO_CONCURRENCY, async (path) => {
43
+ const files = await mapWithConcurrency(productPaths, RELEASE_FILE_IO_CONCURRENCY, async (path) => {
25
44
  const source = resolveWithin(payload.packageRoot, path);
26
45
  const destination = resolveWithin(candidate, path);
27
46
  const metadata = await lstat(source);
@@ -41,7 +60,12 @@ export async function materializeRelease(packageRoot, dataDir, options = {}) {
41
60
  options.onOperation?.({ operation: "candidate-write", path, bytes: bytes.length });
42
61
  return releaseFileIdentity(path, bytes, (metadata.mode & 0o111) !== 0);
43
62
  });
44
- const identity = createReleaseIdentity(payload.packageRoot, payload.packageVersion, files);
63
+ const identity = createReleaseIdentity(payload.packageRoot, payload.packageVersion, files, layerReferences);
64
+ if (layer !== null) {
65
+ const binding = resolveWithin(candidate, "node_modules");
66
+ const target = resolveWithin(layer.layerRoot, "node_modules");
67
+ await symlink(target, binding, process.platform === "win32" ? "junction" : "dir");
68
+ }
45
69
  const releaseRoot = resolveWithin(storeRoot, identity.releaseId);
46
70
  if (await lstat(releaseRoot).catch(() => null)) {
47
71
  await rm(candidate, { recursive: true, force: true });
@@ -71,10 +95,10 @@ export function consumeMaterializationProof(release) {
71
95
  certificationReady.delete(release);
72
96
  return true;
73
97
  }
74
- export async function readMaterializedRelease(releaseRoot) {
98
+ export async function readMaterializedRelease(releaseRoot, selectedStoreRoot) {
75
99
  const canonical = await realpath(releaseRoot);
76
100
  const manifest = JSON.parse(await readFile(resolve(canonical, RELEASE_MANIFEST_FILENAME), "utf8"));
77
- return await verifyMaterializedRelease(canonical, manifest);
101
+ return certificationReadyRelease(await verifyMaterializedRelease(canonical, manifest, selectedStoreRoot));
78
102
  }
79
103
  /**
80
104
  * Load metadata for a release whose bytes were already certified by the
@@ -82,9 +106,10 @@ export async function readMaterializedRelease(releaseRoot) {
82
106
  * establish one of those preconditions; untrusted releases require full
83
107
  * verification.
84
108
  */
85
- export async function readCertifiedReleaseManifest(record, selectedStoreRoot) {
109
+ export async function readCertifiedReleaseManifest(record, selectedStoreRoot, options = {}) {
86
110
  const canonical = await realpath(record.releaseRoot);
87
- assertContained(await realpath(selectedStoreRoot), canonical, "release root is outside the selected release store");
111
+ const canonicalStoreRoot = await realpath(selectedStoreRoot);
112
+ assertContained(canonicalStoreRoot, canonical, "release root is outside the selected release store");
88
113
  const manifest = JSON.parse(await readFile(resolveWithin(canonical, RELEASE_MANIFEST_FILENAME), "utf8"));
89
114
  validateManifest(manifest);
90
115
  if (manifest.releaseId !== record.releaseId || manifest.contentDigest !== record.contentDigest
@@ -93,12 +118,13 @@ export async function readCertifiedReleaseManifest(record, selectedStoreRoot) {
93
118
  }
94
119
  if (canonical.split(sep).at(-1) !== manifest.releaseId)
95
120
  throw new Error(`release directory does not match identity ${manifest.releaseId}`);
121
+ await verifyReleaseDependencies(canonical, canonicalStoreRoot, manifest.dependencyLayers ?? [], false, {}, options);
96
122
  return { ...manifest, releaseRoot: canonical };
97
123
  }
98
124
  export async function verifyMaterializedRelease(releaseRoot, expected, selectedStoreRoot, options = {}) {
99
125
  const canonical = await realpath(releaseRoot);
100
- if (selectedStoreRoot)
101
- assertContained(await realpath(selectedStoreRoot), canonical, "release root is outside the selected release store");
126
+ const canonicalStoreRoot = selectedStoreRoot ? await realpath(selectedStoreRoot) : await realpath(dirname(canonical));
127
+ assertContained(canonicalStoreRoot, canonical, "release root is outside the selected release store");
102
128
  const manifestPath = resolveWithin(canonical, RELEASE_MANIFEST_FILENAME);
103
129
  const manifest = JSON.parse(await readFile(manifestPath, "utf8"));
104
130
  validateManifest(manifest);
@@ -111,9 +137,10 @@ export async function verifyMaterializedRelease(releaseRoot, expected, selectedS
111
137
  await mapWithConcurrency(manifest.files, RELEASE_FILE_IO_CONCURRENCY, async (file) => {
112
138
  await verifyFile(canonical, file, options);
113
139
  });
114
- const recomputed = digestManifestFiles(manifest.files);
140
+ const recomputed = createReleaseIdentity(manifest.packageRoot, manifest.packageVersion, manifest.files, manifest.dependencyLayers ?? []).contentDigest;
115
141
  if (recomputed !== manifest.contentDigest)
116
142
  throw new Error(`release content digest mismatch for ${manifest.releaseId}`);
143
+ await verifyReleaseDependencies(canonical, canonicalStoreRoot, manifest.dependencyLayers ?? [], true, options);
117
144
  return { ...manifest, releaseRoot: canonical };
118
145
  }
119
146
  export async function assertImmutableExecutionRoot(release, dataDir) {
@@ -135,6 +162,25 @@ export async function resolveReleaseEntryPoint(release, entryPoint) {
135
162
  assertContained(release.releaseRoot, canonical, "entry point resolves outside the selected release root");
136
163
  return canonical;
137
164
  }
165
+ async function verifyReleaseDependencies(releaseRoot, storeRoot, references, fullVerification, options = {}, certificationOptions = {}) {
166
+ if (references.length === 0)
167
+ return;
168
+ if (references.length !== 1)
169
+ throw new Error("release currently supports exactly one dependency layer");
170
+ const dataDir = dirname(storeRoot);
171
+ const reference = references[0];
172
+ const layer = fullVerification
173
+ ? await verifyDependencyLayer(dataDir, reference, event => options.onOperation?.({ operation: event.operation, path: event.path, bytes: event.bytes }))
174
+ : await readCertifiedDependencyLayer(dataDir, reference.layerId, reference, certificationOptions);
175
+ const binding = resolveWithin(releaseRoot, reference.binding);
176
+ const metadata = await lstat(binding);
177
+ if (!metadata.isSymbolicLink())
178
+ throw new Error(`release dependency binding is not managed: ${binding}`);
179
+ const target = await realpath(binding);
180
+ const expected = await realpath(resolveWithin(layer.layerRoot, "node_modules"));
181
+ if (target !== expected)
182
+ throw new Error(`release dependency binding targets unexpected content: ${target}`);
183
+ }
138
184
  async function verifyFile(root, file, options) {
139
185
  const path = resolveWithin(root, file.path);
140
186
  const metadata = await lstat(path).catch(() => null);
@@ -142,6 +188,7 @@ async function verifyFile(root, file, options) {
142
188
  throw new Error(`release candidate is incomplete: ${file.path}`);
143
189
  if (metadata.size !== file.bytes)
144
190
  throw new Error(`release file size mismatch: ${file.path}`);
191
+ assertImmutableFileMode(metadata, path);
145
192
  const bytes = await readFile(path);
146
193
  options.onOperation?.({ operation: "verification-read", path: file.path, bytes: bytes.length });
147
194
  const digest = createHash("sha256").update(bytes).digest("hex");
@@ -159,6 +206,11 @@ function validateManifest(value) {
159
206
  throw new Error(PRODUCT_TEXT.diagnostic("release identity is invalid"));
160
207
  if (!Array.isArray(value.files) || value.files.length === 0)
161
208
  throw new Error("release manifest contains no files");
209
+ if (value.dependencyLayers !== undefined && (!Array.isArray(value.dependencyLayers) || value.dependencyLayers.length === 0
210
+ || value.dependencyLayers.some(layer => !/^dependencies-[a-f0-9]{32}$/.test(layer.layerId)
211
+ || !/^[a-f0-9]{64}$/.test(layer.contentDigest) || layer.binding !== "node_modules"))) {
212
+ throw new Error("release dependency-layer references are invalid");
213
+ }
162
214
  for (const file of value.files) {
163
215
  if (typeof file.path !== "string" || file.path.length === 0 || file.path.includes("\\") || file.path.startsWith("/") || file.path.split("/").includes("..")) {
164
216
  throw new Error(`invalid release manifest path: ${String(file.path)}`);
@@ -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;
@@ -12,6 +13,8 @@ export interface ReleaseIdentity {
12
13
  readonly releaseId: string;
13
14
  readonly packageRoot: string;
14
15
  readonly files: readonly ReleaseFileIdentity[];
16
+ /** Absent for legacy full-copy releases. */
17
+ readonly dependencyLayers?: readonly DependencyLayerReference[];
15
18
  }
16
19
  export interface DiscoveredReleasePayload {
17
20
  readonly packageRoot: string;
@@ -31,7 +34,7 @@ export declare function discoverReleasePayload(packageRoot: string, options?: Di
31
34
  * content.
32
35
  */
33
36
  export declare function deriveReleaseIdentity(packageRoot: string): Promise<ReleaseIdentity>;
34
- export declare function createReleaseIdentity(packageRoot: string, packageVersion: string, files: readonly ReleaseFileIdentity[]): ReleaseIdentity;
37
+ export declare function createReleaseIdentity(packageRoot: string, packageVersion: string, files: readonly ReleaseFileIdentity[], dependencyLayers?: readonly DependencyLayerReference[]): ReleaseIdentity;
35
38
  export declare function releaseFileIdentity(path: string, bytes: Uint8Array, executable: boolean): ReleaseFileIdentity;
36
39
  export declare function digestManifestFiles(files: readonly ReleaseFileIdentity[]): string;
37
40
  export declare function resolveWithin(root: string, candidate: string): string;
@@ -51,8 +51,14 @@ export async function deriveReleaseIdentity(packageRoot) {
51
51
  });
52
52
  return createReleaseIdentity(payload.packageRoot, payload.packageVersion, files);
53
53
  }
54
- export function createReleaseIdentity(packageRoot, packageVersion, files) {
55
- const contentDigest = digestManifestFiles(files);
54
+ export function createReleaseIdentity(packageRoot, packageVersion, files, dependencyLayers = []) {
55
+ const productDigest = digestManifestFiles(files);
56
+ const contentDigest = dependencyLayers.length === 0
57
+ ? productDigest
58
+ : createHash("sha256")
59
+ .update(`product\0${productDigest}\n`)
60
+ .update(dependencyLayers.map(layer => `${layer.layerId}\0${layer.contentDigest}\0${layer.binding}\n`).join(""))
61
+ .digest("hex");
56
62
  return {
57
63
  packageName: PRODUCT_PACKAGE_NAME,
58
64
  packageVersion,
@@ -60,6 +66,7 @@ export function createReleaseIdentity(packageRoot, packageVersion, files) {
60
66
  releaseId: `${packageVersion}-${contentDigest.slice(0, 20)}`,
61
67
  packageRoot,
62
68
  files: [...files].sort(compareReleaseFiles),
69
+ ...(dependencyLayers.length === 0 ? {} : { dependencyLayers: [...dependencyLayers] }),
63
70
  };
64
71
  }
65
72
  export function releaseFileIdentity(path, bytes, executable) {
@@ -143,7 +150,7 @@ async function findInstalledDependency(root, requesterRoot, name) {
143
150
  const metadata = await lstat(candidate).catch(() => null);
144
151
  if (metadata?.isDirectory() && !metadata.isSymbolicLink())
145
152
  return candidate;
146
- // A linked dependency directory is how this installation unifies a module
153
+ // Invariant: a linked dependency directory is how this installation unifies a module
147
154
  // that would otherwise be present twice, and the link is made by A1 itself
148
155
  // at install and at every launch. Follow it to the directory it names and
149
156
  // collect from there, so the payload still reads only real files — but
@@ -0,0 +1,67 @@
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 platform: NodeJS.Platform;
29
+ readonly platformPolicy: ImmutablePlatformPolicy;
30
+ readonly releaseId: string;
31
+ readonly packageVersion: string;
32
+ readonly contentDigest: string;
33
+ readonly packageRoot: string;
34
+ readonly releaseRoot: PathEvidence;
35
+ readonly manifest: PathEvidence;
36
+ readonly launchEntries: readonly ReleaseFileIdentity[];
37
+ readonly launchEntryEvidence: readonly PathEvidence[];
38
+ readonly dependencyLayers: readonly LayerRestartEvidence[];
39
+ readonly certifiedAt: string;
40
+ }
41
+ export interface RestartSeal extends RestartSealCore {
42
+ readonly sealDigest: string;
43
+ }
44
+ interface ReleaseCertificationDocument {
45
+ readonly schema: typeof PRODUCT_IDENTITY.evidence.releaseCertificationSchema;
46
+ readonly releaseId: string;
47
+ readonly contentDigest: string;
48
+ readonly verifiedAt: string;
49
+ readonly checks: readonly {
50
+ readonly id: string;
51
+ readonly passed: boolean;
52
+ }[];
53
+ readonly restartSeal: RestartSeal | null;
54
+ }
55
+ export interface RestartValidationEvent {
56
+ readonly operation: "restart-evidence-read";
57
+ readonly path: string;
58
+ }
59
+ /** Build compact restart authority after complete content verification established read-only payload files. */
60
+ export declare function createRestartSeal(release: MaterializedRelease, dataDir: string): Promise<RestartSeal | null>;
61
+ /** Recover an approved release from durable bounded evidence without traversing its payload. */
62
+ export declare function readRestartCertifiedRelease(record: CertifiedReleaseRecord & {
63
+ readonly diagnosticsPath?: string | null;
64
+ }, dataDir: string, onEvent?: (event: RestartValidationEvent) => void): Promise<MaterializedRelease>;
65
+ export declare function releaseCertificationDocument(release: MaterializedRelease, restartSeal: RestartSeal | null, verifiedAt?: string): ReleaseCertificationDocument;
66
+ export declare function restartSealDigest(core: RestartSealCore): string;
67
+ export {};
@@ -0,0 +1,211 @@
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 { DEPENDENCY_LAYER_MANIFEST, dependencyLayerCertificationPath } from "./dependency-layer.js";
6
+ import { immutablePlatformPolicy } from "./immutable-platform.js";
7
+ import { PRODUCT_PACKAGE_NAME } from "./release.js";
8
+ import { RELEASE_MANIFEST_FILENAME } from "./release-store.js";
9
+ import { UpdateTransactionStore } from "./update-transaction.js";
10
+ const RESTART_SEAL_VERSION = 1;
11
+ const REQUIRED_LAUNCH_ENTRIES = ["bin/supervisor.js", "bin/guardian.js"];
12
+ /** Build compact restart authority after complete content verification established read-only payload files. */
13
+ export async function createRestartSeal(release, dataDir) {
14
+ const policy = immutablePlatformPolicy();
15
+ if (policy === null)
16
+ return null;
17
+ const canonicalData = await realpath(dataDir);
18
+ const releasesRoot = await realpath(resolve(canonicalData, "releases"));
19
+ const releaseRoot = await realpath(release.releaseRoot);
20
+ assertDirectChild(releasesRoot, releaseRoot, release.releaseId, "release");
21
+ const manifestPath = resolve(releaseRoot, RELEASE_MANIFEST_FILENAME);
22
+ const launchEntries = REQUIRED_LAUNCH_ENTRIES.map(path => release.files.find(candidate => candidate.path === path));
23
+ if (launchEntries.some(file => file === undefined))
24
+ return null;
25
+ const certifiedLaunchEntries = launchEntries;
26
+ const layersRoot = release.dependencyLayers?.length ? await realpath(resolve(canonicalData, "dependency-layers")) : null;
27
+ const dependencyLayers = await Promise.all((release.dependencyLayers ?? []).map(async (reference) => {
28
+ if (layersRoot === null)
29
+ throw new Error("restart certification has no dependency-layer root");
30
+ const layerRoot = await realpath(resolve(layersRoot, reference.layerId));
31
+ assertDirectChild(layersRoot, layerRoot, reference.layerId, "dependency layer");
32
+ const bindingPath = resolve(releaseRoot, reference.binding);
33
+ const bindingTarget = await realpath(bindingPath);
34
+ const expectedTarget = await realpath(resolve(layerRoot, "node_modules"));
35
+ if (bindingTarget !== expectedTarget)
36
+ throw new Error(`restart certification dependency binding targets unexpected content: ${bindingPath}`);
37
+ return {
38
+ ...reference,
39
+ layerRoot: await pathEvidence(layerRoot, "directory"),
40
+ manifest: await pathEvidence(resolve(layerRoot, DEPENDENCY_LAYER_MANIFEST), "file"),
41
+ certification: await pathEvidence(dependencyLayerCertificationPath(canonicalData, reference.layerId), "file"),
42
+ bindingEvidence: await pathEvidence(bindingPath, "binding", true),
43
+ bindingTarget,
44
+ };
45
+ }));
46
+ const core = {
47
+ version: RESTART_SEAL_VERSION,
48
+ platform: process.platform,
49
+ platformPolicy: policy,
50
+ releaseId: release.releaseId,
51
+ packageVersion: release.packageVersion,
52
+ contentDigest: release.contentDigest,
53
+ packageRoot: release.packageRoot,
54
+ releaseRoot: await pathEvidence(releaseRoot, "directory"),
55
+ manifest: await pathEvidence(manifestPath, "file"),
56
+ launchEntries: certifiedLaunchEntries,
57
+ launchEntryEvidence: await Promise.all(certifiedLaunchEntries.map(file => pathEvidence(resolve(releaseRoot, file.path), "file"))),
58
+ dependencyLayers,
59
+ certifiedAt: new Date().toISOString(),
60
+ };
61
+ return { ...core, sealDigest: restartSealDigest(core) };
62
+ }
63
+ /** Recover an approved release from durable bounded evidence without traversing its payload. */
64
+ export async function readRestartCertifiedRelease(record, dataDir, onEvent) {
65
+ const transaction = await new UpdateTransactionStore(dataDir).read();
66
+ if (transaction?.status === "active")
67
+ throw new Error("restart certification is unavailable during an active update transaction");
68
+ const certificationPath = resolve(dataDir, `certification-${record.releaseId}.json`);
69
+ if (record.diagnosticsPath !== undefined && record.diagnosticsPath !== certificationPath) {
70
+ throw new Error("restart certification path differs from the approved release record");
71
+ }
72
+ const certificationMetadata = await lstat(certificationPath);
73
+ onEvent?.({ operation: "restart-evidence-read", path: certificationPath });
74
+ if (!certificationMetadata.isFile() || certificationMetadata.isSymbolicLink() || (certificationMetadata.mode & 0o222) !== 0) {
75
+ throw new Error("restart certification is not an immutable regular file");
76
+ }
77
+ const certification = await readJson(certificationPath, onEvent);
78
+ if (certification.schema !== PRODUCT_IDENTITY.evidence.releaseCertificationSchema
79
+ || certification.releaseId !== record.releaseId || certification.contentDigest !== record.contentDigest
80
+ || !certification.checks.some(check => check.id === "immutable-content" && check.passed)) {
81
+ throw new Error("restart certification differs from the approved release record");
82
+ }
83
+ const seal = normalizeRestartSeal(certification.restartSeal);
84
+ if (seal.platform !== process.platform || seal.platformPolicy !== immutablePlatformPolicy()) {
85
+ throw new Error("restart certification platform immutability evidence is unsupported");
86
+ }
87
+ if (seal.releaseId !== record.releaseId || seal.contentDigest !== record.contentDigest
88
+ || resolve(seal.releaseRoot.path) !== resolve(record.releaseRoot)
89
+ || (record.packageVersion !== undefined && seal.packageVersion !== record.packageVersion)) {
90
+ throw new Error("restart seal differs from the approved release identity");
91
+ }
92
+ const { sealDigest, ...core } = seal;
93
+ if (restartSealDigest(core) !== sealDigest)
94
+ throw new Error("restart seal digest is invalid");
95
+ const canonicalData = await observedRealpath(dataDir, onEvent);
96
+ const releasesRoot = await observedRealpath(resolve(canonicalData, "releases"), onEvent);
97
+ const releaseRoot = await observedRealpath(seal.releaseRoot.path, onEvent);
98
+ assertDirectChild(releasesRoot, releaseRoot, seal.releaseId, "release");
99
+ await assertPathEvidence(seal.releaseRoot, onEvent);
100
+ await assertPathEvidence(seal.manifest, onEvent);
101
+ for (let index = 0; index < seal.launchEntries.length; index += 1) {
102
+ const file = seal.launchEntries[index];
103
+ if (!REQUIRED_LAUNCH_ENTRIES.includes(file.path)) {
104
+ throw new Error(`restart seal contains an unexpected launch entry: ${file.path}`);
105
+ }
106
+ const evidence = seal.launchEntryEvidence[index];
107
+ if (!evidence || evidence.path !== resolve(releaseRoot, file.path) || file.bytes !== Number(evidence.size)) {
108
+ throw new Error(`restart launch entry evidence differs: ${file.path}`);
109
+ }
110
+ await assertPathEvidence(evidence, onEvent);
111
+ }
112
+ if (seal.launchEntries.length !== REQUIRED_LAUNCH_ENTRIES.length)
113
+ throw new Error("restart seal launch entries are incomplete");
114
+ const layersRoot = seal.dependencyLayers.length ? await observedRealpath(resolve(canonicalData, "dependency-layers"), onEvent) : null;
115
+ for (const layer of seal.dependencyLayers) {
116
+ if (layersRoot === null)
117
+ throw new Error("restart seal has no dependency-layer root");
118
+ const layerRoot = await observedRealpath(layer.layerRoot.path, onEvent);
119
+ assertDirectChild(layersRoot, layerRoot, layer.layerId, "dependency layer");
120
+ await assertPathEvidence(layer.layerRoot, onEvent);
121
+ await assertPathEvidence(layer.manifest, onEvent);
122
+ await assertPathEvidence(layer.certification, onEvent);
123
+ await assertPathEvidence(layer.bindingEvidence, onEvent, true);
124
+ const bindingTarget = await observedRealpath(layer.bindingEvidence.path, onEvent);
125
+ const expectedTarget = await observedRealpath(resolve(layerRoot, "node_modules"), onEvent);
126
+ if (bindingTarget !== layer.bindingTarget || bindingTarget !== expectedTarget) {
127
+ throw new Error(`restart dependency binding targets unexpected content: ${layer.bindingEvidence.path}`);
128
+ }
129
+ }
130
+ return {
131
+ packageName: PRODUCT_PACKAGE_NAME,
132
+ packageVersion: seal.packageVersion,
133
+ contentDigest: seal.contentDigest,
134
+ releaseId: seal.releaseId,
135
+ packageRoot: seal.packageRoot,
136
+ files: seal.launchEntries,
137
+ ...(seal.dependencyLayers.length === 0 ? {} : {
138
+ dependencyLayers: seal.dependencyLayers.map(({ layerId, contentDigest, binding }) => ({ layerId, contentDigest, binding })),
139
+ }),
140
+ releaseRoot,
141
+ };
142
+ }
143
+ export function releaseCertificationDocument(release, restartSeal, verifiedAt = new Date().toISOString()) {
144
+ return {
145
+ schema: PRODUCT_IDENTITY.evidence.releaseCertificationSchema,
146
+ releaseId: release.releaseId,
147
+ contentDigest: release.contentDigest,
148
+ verifiedAt,
149
+ checks: [{ id: "immutable-content", passed: true }],
150
+ restartSeal,
151
+ };
152
+ }
153
+ export function restartSealDigest(core) {
154
+ return createHash("sha256").update(JSON.stringify(core)).digest("hex");
155
+ }
156
+ async function assertPathEvidence(evidence, onEvent, symbolic = false) {
157
+ const actual = await pathEvidence(evidence.path, evidence.kind, symbolic, onEvent);
158
+ if (JSON.stringify(actual) !== JSON.stringify(evidence))
159
+ throw new Error(`restart path evidence changed: ${evidence.path}`);
160
+ }
161
+ async function pathEvidence(path, kind, symbolic = false, onEvent) {
162
+ onEvent?.({ operation: "restart-evidence-read", path });
163
+ const metadata = symbolic ? await lstat(path, { bigint: true }) : await stat(path, { bigint: true });
164
+ if ((kind === "directory") !== metadata.isDirectory())
165
+ throw new Error(`restart evidence kind changed: ${path}`);
166
+ if (kind === "file" && !metadata.isFile())
167
+ throw new Error(`restart evidence file changed: ${path}`);
168
+ if (kind === "binding" && !metadata.isSymbolicLink())
169
+ throw new Error(`restart evidence binding changed: ${path}`);
170
+ if (kind === "file" && (metadata.mode & 146n) !== 0n)
171
+ throw new Error(`restart evidence file is writable: ${path}`);
172
+ return {
173
+ path: resolve(path),
174
+ kind,
175
+ device: metadata.dev.toString(),
176
+ inode: metadata.ino.toString(),
177
+ mode: Number(metadata.mode),
178
+ size: metadata.size.toString(),
179
+ modifiedNs: metadata.mtimeNs.toString(),
180
+ changedNs: metadata.ctimeNs.toString(),
181
+ bornNs: metadata.birthtimeNs.toString(),
182
+ };
183
+ }
184
+ function normalizeRestartSeal(value) {
185
+ if (!value || typeof value !== "object" || Array.isArray(value))
186
+ throw new Error("release certification has no durable restart seal");
187
+ const seal = value;
188
+ if (seal.version !== RESTART_SEAL_VERSION || typeof seal.platform !== "string" || typeof seal.platformPolicy !== "string"
189
+ || typeof seal.releaseId !== "string" || typeof seal.packageVersion !== "string" || typeof seal.contentDigest !== "string"
190
+ || typeof seal.packageRoot !== "string" || typeof seal.certifiedAt !== "string" || typeof seal.sealDigest !== "string"
191
+ || !seal.releaseRoot || !seal.manifest || !Array.isArray(seal.launchEntries) || !Array.isArray(seal.launchEntryEvidence)
192
+ || !Array.isArray(seal.dependencyLayers)) {
193
+ throw new Error("durable restart seal is invalid");
194
+ }
195
+ return seal;
196
+ }
197
+ async function readJson(path, onEvent) {
198
+ onEvent?.({ operation: "restart-evidence-read", path });
199
+ return JSON.parse(await readFile(path, "utf8"));
200
+ }
201
+ async function observedRealpath(path, onEvent) {
202
+ onEvent?.({ operation: "restart-evidence-read", path });
203
+ return await realpath(path);
204
+ }
205
+ function assertDirectChild(parent, child, expectedName, kind) {
206
+ const fromParent = relative(parent, child);
207
+ if (isAbsolute(fromParent) || fromParent === ".." || fromParent.startsWith(`..${sep}`) || fromParent.includes(sep)
208
+ || basename(child) !== expectedName) {
209
+ throw new Error(`restart ${kind} is outside its managed store: ${child}`);
210
+ }
211
+ }
@@ -14,6 +14,7 @@ export interface UpdateTransaction {
14
14
  readonly startedAt: string;
15
15
  readonly updatedAt: string;
16
16
  }
17
+ /** Persists the durable update journal and permits only validated forward transaction phases. */
17
18
  export declare class UpdateTransactionStore {
18
19
  #private;
19
20
  readonly path: string;
@@ -3,6 +3,7 @@ import { mkdir, open, readFile, rename, rm } from "node:fs/promises";
3
3
  import { dirname, resolve } from "node:path";
4
4
  import { PRODUCT_IDENTITY, PRODUCT_TEXT } from "../../product-identity.js";
5
5
  export const UPDATE_JOURNAL_SCHEMA = PRODUCT_IDENTITY.protocol.updateJournalSchema;
6
+ /** Persists the durable update journal and permits only validated forward transaction phases. */
6
7
  export class UpdateTransactionStore {
7
8
  path;
8
9
  constructor(dataDir) { this.path = resolve(dataDir, "update-transaction.json"); }
@@ -18,7 +18,7 @@ export interface UpdateOutput {
18
18
  stdout(message: string): void;
19
19
  stderr(message: string): void;
20
20
  }
21
- export type UpdateMeasuredPhase = "package-version" | "target-resolution" | "global-root" | "ownership-release" | "npm-install" | "materialized" | "certified" | "active-reference-committed" | "supervisor-verified" | "transaction-complete";
21
+ export type UpdateMeasuredPhase = "package-version" | "target-resolution" | "global-root" | "ownership-release" | "npm-install" | "materialized" | "certified" | "active-reference-committed" | "warmup" | "supervisor-verified" | "transaction-complete";
22
22
  export interface UpdatePhaseTimingEvent {
23
23
  readonly phase: UpdateMeasuredPhase;
24
24
  readonly durationMs: number;
@@ -28,12 +28,18 @@ export interface UpdatePerformanceEvidence {
28
28
  readonly sourceReads: number;
29
29
  readonly candidateWrites: number;
30
30
  readonly verificationReads: number;
31
+ readonly layerWrites?: number;
32
+ readonly layerReusedFiles?: number;
33
+ readonly layerReusedBytes?: number;
34
+ readonly payloadExcludedFiles?: number;
35
+ readonly payloadExcludedBytes?: number;
36
+ readonly warmupDurationMs?: number;
31
37
  readonly postNpmDurationMs: number;
32
38
  }
33
39
  export interface SelfUpdateOptions {
34
40
  packageRoot: string;
35
41
  channel?: UpdateChannel;
36
- /** A specific preview to install, named by its commit or its full version. */
42
+ /** A specific preview to install, named by its development number or full version. */
37
43
  target?: string;
38
44
  environment?: NodeJS.ProcessEnv;
39
45
  fileSystem?: UpdateFileSystem;
@@ -41,6 +47,8 @@ export interface SelfUpdateOptions {
41
47
  runner?: UpdateProcessRunner;
42
48
  lifecycle?: UpdateLifecycleCoordinator;
43
49
  transactionStore?: UpdateTransactionJournal;
50
+ /** Test or embedding seam for post-activation release maintenance. */
51
+ maintenance?: () => Promise<void>;
44
52
  progress?: boolean;
45
53
  onPhaseTiming?: (event: UpdatePhaseTimingEvent) => void;
46
54
  now?: () => number;
@@ -61,7 +69,7 @@ export interface UpdateLifecycleCoordinator {
61
69
  priorActiveVersion: string | null;
62
70
  }>;
63
71
  verifyPackageUnlocked(packageRoot: string): Promise<void>;
64
- activateInstalled(packageRoot: string, targetVersion: string, phase: (phase: UpdateActivationPhase) => Promise<void>, onMaterializing?: (progress: UpdateMaterializationProgress) => void): Promise<void>;
72
+ activateInstalled(packageRoot: string, targetVersion: string, phase: (phase: UpdateActivationPhase) => Promise<void>, onMaterializing?: (progress: UpdateMaterializationProgress) => void, onWarmup?: (state: "started" | "completed") => void): Promise<void>;
65
73
  }
66
74
  export interface UpdateTransactionJournal {
67
75
  readonly path: string;
@@ -77,6 +85,14 @@ export interface UpdateTransactionJournal {
77
85
  clearCompleted(): Promise<void>;
78
86
  }
79
87
  export declare function createNpmProcessRunner(platform?: NodeJS.Platform): UpdateProcessRunner;
88
+ export type UpdateOwnershipAction = "clean-dead-record" | "leave-running" | "end-session";
89
+ /**
90
+ * What an update does about the owner it found. A cohort running from retained immutable
91
+ * content keeps its work: the installation replaces files it does not read, and it listens on
92
+ * its own endpoint. A cohort running from the mutable installation is the one exception,
93
+ * because that installation is exactly what is about to be replaced under it.
94
+ */
95
+ export declare function planUpdateOwnership(ownership: "live-verified" | "dead", runsFromRetainedRelease: boolean): UpdateOwnershipAction;
80
96
  export declare function createUpdateLifecycleCoordinator(environment?: NodeJS.ProcessEnv, fileSystem?: UpdateFileSystem, output?: UpdateOutput): UpdateLifecycleCoordinator;
81
97
  export declare function runSelfUpdate(options: SelfUpdateOptions): Promise<number>;
82
98
  export declare function assertUpdatePerformanceBudget(evidence: UpdatePerformanceEvidence, maximumPostNpmDurationMs?: number): void;