@moretea-labs/forge 1.8.0 → 1.8.1

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 (528) hide show
  1. package/AGENTS.md +70 -7
  2. package/CHANGELOG.md +14 -0
  3. package/CLAUDE.md +17 -2
  4. package/CONTRIBUTING.md +3 -2
  5. package/THIRD_PARTY_NOTICES.md +1 -1
  6. package/adapters/chatgpt/browser-delivery-host.ts +7 -1
  7. package/adapters/chatgpt/browser-delivery-runtime.ts +529 -56
  8. package/adapters/chatgpt/controller-binding-store.ts +101 -22
  9. package/adapters/chatgpt/controller-round-host.ts +15 -25
  10. package/adapters/chatgpt/controller-round-settlement-store.ts +58 -4
  11. package/adapters/chatgpt/provider-delivery.ts +228 -1
  12. package/adapters/chatgpt/work-conversation-binding-store.ts +79 -53
  13. package/adapters/computer/chatgpt-extension-target.ts +463 -0
  14. package/adapters/computer/chatgpt-target-router.ts +103 -0
  15. package/adapters/computer/chrome-extension/background.js +385 -0
  16. package/adapters/computer/chrome-extension/content.js +378 -0
  17. package/adapters/computer/chrome-extension/core.js +24 -0
  18. package/adapters/computer/chrome-extension/manifest.json +30 -0
  19. package/adapters/computer/desktop-operator-discovery.ts +11 -31
  20. package/adapters/computer/interaction-target-authority.ts +142 -18
  21. package/adapters/mcp/auth.ts +0 -1
  22. package/adapters/mcp/instructions.ts +5 -4
  23. package/adapters/mcp/multi-repository.ts +3 -19
  24. package/adapters/mcp/oauth.ts +73 -0
  25. package/adapters/mcp/paths.ts +4 -1
  26. package/adapters/mcp/runtime-gateway/automation-receipt-adapter.ts +87 -0
  27. package/adapters/mcp/runtime-gateway/bounded-result-runtime.ts +62 -0
  28. package/adapters/mcp/runtime-gateway/cognition-settlement.ts +201 -0
  29. package/adapters/mcp/runtime-gateway/context-adapter.ts +411 -73
  30. package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +91 -0
  31. package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +20 -5
  32. package/adapters/mcp/runtime-gateway/core-capability-adapter.ts +258 -0
  33. package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +10 -27
  34. package/adapters/mcp/runtime-gateway/engineering-tool-contract.ts +15 -0
  35. package/adapters/mcp/runtime-gateway/execution-tools.ts +8 -42
  36. package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +2 -1
  37. package/adapters/mcp/runtime-gateway/plugin-adapter.ts +117 -45
  38. package/adapters/mcp/runtime-gateway/process-tools.ts +190 -22
  39. package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +16 -4
  40. package/adapters/mcp/runtime-gateway/recovery-adapter.ts +69 -52
  41. package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +4 -35
  42. package/adapters/mcp/runtime-gateway/result-adapter.ts +10 -4
  43. package/adapters/mcp/runtime-gateway/router.ts +18 -504
  44. package/adapters/mcp/runtime-gateway/routing-policy.ts +499 -0
  45. package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +14 -65
  46. package/adapters/mcp/runtime-gateway/runtime-readiness-observation.ts +218 -0
  47. package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +113 -173
  48. package/adapters/mcp/runtime-gateway/runtime-tools.ts +15 -5
  49. package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +1 -0
  50. package/adapters/mcp/runtime-gateway/shared-adapter.ts +20 -0
  51. package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +358 -266
  52. package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +136 -0
  53. package/adapters/mcp/runtime-gateway/work-adapter.ts +261 -3122
  54. package/adapters/mcp/runtime-gateway/work-controller-operations.ts +257 -0
  55. package/adapters/mcp/runtime-gateway/work-detail-projection.ts +60 -0
  56. package/adapters/mcp/runtime-gateway/work-input-wire-migration.ts +246 -0
  57. package/adapters/mcp/runtime-gateway/work-learning-operations.ts +145 -0
  58. package/adapters/mcp/runtime-gateway/work-list-projection.ts +38 -0
  59. package/adapters/mcp/runtime-gateway/work-plan-operations.ts +382 -0
  60. package/adapters/mcp/runtime-gateway/work-repair-adapter.ts +308 -0
  61. package/adapters/mcp/runtime-gateway/work-requirement-operations.ts +148 -0
  62. package/adapters/mcp/runtime-gateway/work-semantic-operations.ts +263 -0
  63. package/adapters/mcp/runtime-gateway/work-workflow-operations.ts +113 -0
  64. package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +156 -0
  65. package/adapters/mcp/server.ts +67 -23
  66. package/adapters/mcp/setup.ts +1 -3
  67. package/adapters/mcp/tool-mapping/legacy-tool-service.ts +44 -170
  68. package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +4 -9
  69. package/adapters/mcp/tool-mapping/repository-tools.ts +133 -142
  70. package/adapters/mcp/toolset-names.ts +5 -0
  71. package/adapters/mcp/toolset.ts +6 -5
  72. package/adapters/mcp/transports/http-observation.ts +365 -0
  73. package/adapters/mcp/transports/http.ts +154 -677
  74. package/adapters/mcp/transports/oauth-http.ts +322 -0
  75. package/adapters/mcp/transports/session-registry.ts +6 -0
  76. package/adapters/mcp/tunnels/openai-secure-tunnel.ts +89 -5
  77. package/assets/plugin-registry.v1.json +6 -4
  78. package/assets/reference-configs/agentic-development-flow.md +25 -0
  79. package/assets/reference-configs/global-working-rules.md +19 -0
  80. package/assets/skill-version.json +2 -2
  81. package/docs/architecture/CURRENT.md +111 -41
  82. package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +14 -5
  83. package/docs/architecture/decisions/20260823-immediate-controller-relay.md +6 -3
  84. package/docs/architecture/decisions/20260907-assistant-learning-loop.md +2 -0
  85. package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +19 -4
  86. package/docs/architecture/decisions/20260916-workflow-supervisor-authority.md +249 -0
  87. package/docs/architecture/decisions/20260917-cognitive-memory-foundation.md +82 -0
  88. package/docs/architecture/decisions/20260918-stable-candidate-release-lifecycle.md +221 -0
  89. package/docs/architecture/decisions/20260919-autonomous-work-liveness.md +62 -0
  90. package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +72 -0
  91. package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +237 -0
  92. package/docs/architecture/decisions/20261005-forge-v3-desktop-client-boundary.md +77 -0
  93. package/docs/architecture/domains/verification.md +1 -0
  94. package/docs/architecture/domains/workflow-engine.md +6 -0
  95. package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +1 -1
  96. package/docs/forge-plugin-management.md +2 -2
  97. package/docs/operations/controller-performance-and-502.md +17 -0
  98. package/docs/operations/controller-reliability-runbook.md +2 -2
  99. package/docs/operations/features.md +1 -1
  100. package/docs/operations/features.zh-CN.md +1 -1
  101. package/docs/operations/homebrew.md +2 -2
  102. package/docs/operations/mcp-tool-exposure.md +2 -0
  103. package/docs/operations/releasing.md +2 -0
  104. package/docs/operations/standalone-disaster-recovery.md +14 -6
  105. package/docs/wiki/Implementation.md +1 -1
  106. package/package.json +25 -14
  107. package/packages/kernel/cognition/api/index.ts +6 -0
  108. package/packages/kernel/cognition/application/activation-service.ts +451 -0
  109. package/packages/kernel/cognition/application/consolidation-service.ts +185 -0
  110. package/packages/kernel/cognition/application/legacy-experience-adapter.ts +38 -0
  111. package/packages/kernel/cognition/application/memory-service.ts +64 -0
  112. package/packages/kernel/cognition/domain/learning.ts +106 -0
  113. package/packages/kernel/cognition/domain/memory.ts +254 -0
  114. package/packages/kernel/controller/api/index.ts +1 -0
  115. package/packages/kernel/controller/application/continuation-service.ts +281 -0
  116. package/packages/kernel/controller/application/controller-round-service.ts +12 -0
  117. package/packages/kernel/controller/domain/controller-round-transition-policy.ts +242 -21
  118. package/packages/kernel/controller/domain/controller-round.ts +4 -1
  119. package/packages/kernel/controller/domain/execution-quality.ts +3 -1
  120. package/packages/kernel/controller/infrastructure/controller-round-store.ts +689 -103
  121. package/packages/kernel/controller/infrastructure/controller-session-store.ts +297 -71
  122. package/packages/kernel/controller/ports/controller-host.ts +2 -0
  123. package/packages/kernel/identity/api/index.ts +10 -0
  124. package/packages/kernel/identity/domain/activity-projection.ts +43 -0
  125. package/packages/kernel/identity/domain/capability-broker.ts +60 -0
  126. package/packages/kernel/identity/domain/grant.ts +72 -0
  127. package/packages/kernel/identity/domain/owned-resource.ts +116 -0
  128. package/packages/kernel/identity/domain/user-request.ts +93 -0
  129. package/packages/kernel/identity/infrastructure/activity-projection-store.ts +77 -0
  130. package/packages/kernel/identity/infrastructure/capability-broker.ts +81 -0
  131. package/packages/kernel/identity/infrastructure/grant-store.ts +284 -0
  132. package/packages/kernel/identity/infrastructure/owned-resource-store.ts +259 -0
  133. package/packages/kernel/identity/infrastructure/user-request-store.ts +182 -0
  134. package/packages/kernel/scheduler/api/index.ts +0 -2
  135. package/packages/kernel/scheduler/application/schedule-service.ts +3 -0
  136. package/packages/kernel/scheduler/application/settlement.ts +0 -15
  137. package/packages/kernel/scheduler/domain/schedule.ts +87 -0
  138. package/packages/kernel/scheduler/infrastructure/schedule-store.ts +153 -133
  139. package/packages/kernel/work/api/index.ts +3 -2
  140. package/packages/kernel/work/application/work-service.ts +17 -42
  141. package/packages/kernel/work/domain/current-task-lineage.ts +104 -0
  142. package/packages/kernel/work/domain/engineering-design.ts +10 -5
  143. package/packages/kernel/work/domain/engineering-profile.ts +8 -12
  144. package/packages/kernel/work/domain/evaluation-promotion-receipt.ts +186 -0
  145. package/packages/kernel/work/domain/execution-concurrency.ts +19 -26
  146. package/packages/kernel/work/domain/execution-snapshot.ts +0 -31
  147. package/packages/kernel/work/domain/implementation-review.ts +14 -331
  148. package/packages/kernel/work/domain/objective-graph.ts +119 -0
  149. package/packages/kernel/work/domain/project-engineering-contract.ts +23 -1
  150. package/packages/kernel/work/domain/repository-completion-receipt.ts +1 -1
  151. package/packages/kernel/work/domain/state-machine.ts +25 -63
  152. package/packages/kernel/work/domain/types.ts +57 -51
  153. package/packages/kernel/work/infrastructure/work-contract-store.ts +819 -728
  154. package/packages/kernel/work/ports/work-contract-store.ts +5 -2
  155. package/packages/plugin-runtime/browser/session-authority.ts +2 -1
  156. package/packages/plugin-runtime/computer/chatgpt-identity.ts +24 -0
  157. package/packages/plugin-runtime/computer/conversation-target.ts +143 -0
  158. package/packages/plugin-runtime/computer/index.ts +2 -0
  159. package/packages/plugin-runtime/computer/target-authority.ts +26 -1
  160. package/packages/plugin-runtime/external/unix-jsonl-transport.ts +142 -18
  161. package/packages/protocols/computer/contract.ts +27 -1
  162. package/scripts/activate-source-baseline.ts +7 -9
  163. package/scripts/canary-controller-semantic-wait.ts +12 -24
  164. package/scripts/check-mcp-compatibility.ts +48 -136
  165. package/scripts/check-runtime-architecture.mjs +622 -217
  166. package/scripts/forge-local-recovery-helper.mjs +93 -15
  167. package/scripts/lib/project-init-lib.sh +3 -0
  168. package/scripts/open-source-audit-allowlist.txt +1 -2
  169. package/scripts/run-bounded-command.mjs +5 -0
  170. package/scripts/run-governed-gate.ts +0 -1
  171. package/scripts/run-mobile-monitor-bridge.ts +0 -1
  172. package/scripts/smoke-control-plane-failure-domain.ts +94 -0
  173. package/scripts/smoke-mcp-http-runtime.ts +5 -0
  174. package/scripts/smoke-runtime-recovery.ts +12 -43
  175. package/scripts/smoke-schedule-engine.ts +23 -15
  176. package/scripts/smoke-unattended-transport-recovery.ts +223 -0
  177. package/scripts/smoke-user-request-continuation-restart.ts +232 -0
  178. package/scripts/smoke-workflow-supervisor-chrome-adapter.ts +92 -0
  179. package/scripts/smoke-workflow-supervisor-process-restart.ts +276 -0
  180. package/scripts/smoke-workflow-supervisor-restart-recovery.ts +150 -0
  181. package/scripts/smoke-workflow-supervisor.ts +103 -0
  182. package/scripts/verify-forge-runtime.sh +2 -1
  183. package/src/cli/agent-jobs/executor-health.ts +11 -34
  184. package/src/cli/agent-jobs/integration.ts +18 -49
  185. package/src/cli/agent-jobs/job-manager.ts +7 -3
  186. package/src/cli/commands/brain-assistant.ts +27 -13
  187. package/src/cli/commands/brain.ts +13 -15
  188. package/src/cli/commands/chatgpt.ts +1 -163
  189. package/src/cli/commands/recovery.ts +135 -121
  190. package/src/cli/commands/runtime.ts +3 -3
  191. package/src/cli/commands/setup-profile.ts +8 -0
  192. package/src/cli/controller/check-runner.ts +13 -2
  193. package/src/cli/controller/completion-backlog.ts +3 -3
  194. package/src/cli/controller/completion-orchestrator.ts +4 -43
  195. package/src/cli/controller/completion-target.ts +3 -72
  196. package/src/cli/controller/context/source-materializer.ts +81 -100
  197. package/src/cli/controller/context-pack.ts +10 -8
  198. package/src/cli/controller/execution-completion.ts +4 -7
  199. package/src/cli/controller/execution-policy.ts +36 -153
  200. package/src/cli/controller/governance.ts +2 -3
  201. package/src/cli/controller/issue-store.ts +4 -99
  202. package/src/cli/controller/launch-agents.ts +59 -18
  203. package/src/cli/controller/operational-plan.ts +24 -51
  204. package/src/cli/controller/runtime-config.ts +5 -1
  205. package/src/cli/controller/stuck-state-migration.ts +2 -3
  206. package/src/cli/controller/systemd-user.ts +39 -1
  207. package/src/cli/editing/edit-session.ts +1 -7
  208. package/src/cli/local-bridge/console-automations.ts +18 -13
  209. package/src/cli/local-bridge/console-view-models.ts +3 -12
  210. package/src/cli/local-bridge/facade-api.ts +64 -191
  211. package/src/cli/local-bridge/server.ts +24 -147
  212. package/src/cli/local-bridge/types.ts +0 -1
  213. package/src/cli/mcp/oauth-client-retirement.ts +74 -0
  214. package/src/cli/repositories/command-executor.ts +29 -23
  215. package/src/cli/repositories/command-scope.ts +35 -16
  216. package/src/cli/repositories/controller-home.ts +48 -0
  217. package/src/cli/repositories/ephemeral-workspace.ts +20 -30
  218. package/src/cli/repositories/git-command-executor.ts +2 -2
  219. package/src/cli/repositories/registry.ts +77 -11
  220. package/src/cli/repositories/structured-git.ts +62 -2
  221. package/src/cli/repository/session-cache.ts +92 -6
  222. package/src/runtime/context/assistant-context.ts +20 -7
  223. package/src/runtime/context/assistant-work-context.ts +89 -27
  224. package/src/runtime/context/automatic-learning.ts +565 -0
  225. package/src/runtime/context/cognitive-attention.ts +173 -0
  226. package/src/runtime/context/cognitive-skill-canary.ts +158 -0
  227. package/src/runtime/context/context-closure.ts +46 -9
  228. package/src/runtime/context/context-pack-process.ts +103 -0
  229. package/src/runtime/context/context-plane.ts +1 -9
  230. package/src/runtime/context/direct-controller-learning.ts +298 -0
  231. package/src/runtime/context/semantic-navigation-contract.ts +9 -0
  232. package/src/runtime/context/semantic-navigation.ts +6 -34
  233. package/src/runtime/context/typescript-navigation-process.ts +145 -0
  234. package/src/runtime/context/typescript-navigation.ts +89 -3
  235. package/src/runtime/control-plane/cleanup-artifact-retention.ts +212 -9
  236. package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +9 -47
  237. package/src/runtime/control-plane/execution/controller-authority-recovery.ts +34 -4
  238. package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +29 -20
  239. package/src/runtime/control-plane/execution/execution-identity.ts +23 -3
  240. package/src/runtime/control-plane/execution/repository-work-attribution.ts +7 -30
  241. package/src/runtime/control-plane/execution/retained-work-resume.ts +206 -199
  242. package/src/runtime/control-plane/execution/session-store.ts +31 -1
  243. package/src/runtime/control-plane/execution/validation.ts +6 -8
  244. package/src/runtime/control-plane/execution/work-authority-reconciler.ts +13 -42
  245. package/src/runtime/control-plane/execution/work-check-evidence.ts +137 -0
  246. package/src/runtime/control-plane/execution/work-completion-authority.ts +30 -85
  247. package/src/runtime/control-plane/execution/work-delivery-service.ts +497 -0
  248. package/src/runtime/control-plane/execution/work-evidence-policy.ts +12 -50
  249. package/src/runtime/control-plane/execution/work-execution-support.ts +50 -149
  250. package/src/runtime/control-plane/execution/work-handle-authority.ts +188 -109
  251. package/src/runtime/control-plane/execution/work-handle-store.ts +19 -43
  252. package/src/runtime/control-plane/execution/work-head-settlement.ts +53 -20
  253. package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +52 -29
  254. package/src/runtime/control-plane/execution/work-operation-service.ts +43 -27
  255. package/src/runtime/control-plane/execution/work-preparation-service.ts +126 -266
  256. package/src/runtime/control-plane/execution/work-remote-delivery.ts +2 -3
  257. package/src/runtime/control-plane/execution/work-revision-diff.ts +39 -0
  258. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +173 -186
  259. package/src/runtime/control-plane/execution/work-validation-reconciler.ts +28 -84
  260. package/src/runtime/control-plane/execution/work-verification-service.ts +406 -50
  261. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +5 -1
  262. package/src/runtime/control-plane/facade/capability-registry.ts +362 -37
  263. package/src/runtime/control-plane/facade/check-normalization.ts +3 -9
  264. package/src/runtime/control-plane/facade/codex-delegation.ts +10 -11
  265. package/src/runtime/control-plane/facade/controller-connection.ts +135 -0
  266. package/src/runtime/control-plane/facade/goal-workloop-access.ts +1 -20
  267. package/src/runtime/control-plane/facade/goal-workloop.ts +281 -1753
  268. package/src/runtime/control-plane/facade/handoff-inbox-application.ts +12 -25
  269. package/src/runtime/control-plane/facade/handoff-inbox-store.ts +256 -52
  270. package/src/runtime/control-plane/facade/index.ts +0 -1
  271. package/src/runtime/control-plane/facade/operation-digest.ts +12 -15
  272. package/src/runtime/control-plane/facade/plan-contract-store.ts +451 -991
  273. package/src/runtime/control-plane/facade/policy-gate.ts +0 -23
  274. package/src/runtime/control-plane/facade/repository-work-admission.ts +12 -22
  275. package/src/runtime/control-plane/facade/requirement-authority.ts +102 -199
  276. package/src/runtime/control-plane/facade/requirement-board.ts +3 -3
  277. package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +51 -14
  278. package/src/runtime/control-plane/facade/self-healing-loop.ts +18 -53
  279. package/src/runtime/control-plane/facade/suggested-actions.ts +15 -18
  280. package/src/runtime/control-plane/facade/types.ts +49 -108
  281. package/src/runtime/control-plane/facade/work-continuation.ts +8 -8
  282. package/src/runtime/control-plane/generated-cache-retention.ts +97 -1
  283. package/src/runtime/control-plane/global-scheduler/autonomous-continuation.ts +248 -0
  284. package/src/runtime/control-plane/global-scheduler/durable-admission.ts +1 -1
  285. package/src/runtime/control-plane/global-scheduler/maintenance.ts +239 -112
  286. package/src/runtime/control-plane/global-scheduler/reconciliation.ts +2 -1
  287. package/src/runtime/control-plane/global-scheduler/scheduler.ts +66 -40
  288. package/src/runtime/control-plane/global-scheduler/wake-signal.ts +42 -2
  289. package/src/runtime/control-plane/governance/access-policy.ts +19 -2
  290. package/src/runtime/control-plane/governance/authorization.ts +20 -3
  291. package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +63 -300
  292. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +28 -300
  293. package/src/runtime/control-plane/launcher/local-conversation-controller.ts +238 -0
  294. package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +5 -2
  295. package/src/runtime/control-plane/launcher/thin-launcher.ts +96 -240
  296. package/src/runtime/control-plane/persistence/cognition-store.ts +820 -0
  297. package/src/runtime/control-plane/persistence/experience-store.ts +162 -29
  298. package/src/runtime/control-plane/persistence/requirement-store.ts +216 -74
  299. package/src/runtime/control-plane/persistence/sqlite-store.ts +113 -6
  300. package/src/runtime/control-plane/release-retention.ts +135 -47
  301. package/src/runtime/control-plane/repository-namespace-retention.ts +2 -2
  302. package/src/runtime/control-plane/runtime-cleanup.ts +290 -21
  303. package/src/runtime/control-plane/workspace/project-onboarding.ts +80 -0
  304. package/src/runtime/control-plane/workspace/semantic-sync-service.ts +19 -5
  305. package/src/runtime/control-plane/workspace/workspace-store.ts +169 -0
  306. package/src/runtime/diagnostics/incident-repair.ts +313 -146
  307. package/src/runtime/diagnostics/mcp-timing.ts +114 -0
  308. package/src/runtime/evidence/artifact-store.ts +158 -40
  309. package/src/runtime/evidence/evidence-store.ts +112 -8
  310. package/src/runtime/evidence/output-handle-index.ts +225 -0
  311. package/src/runtime/evidence/result-store.ts +158 -44
  312. package/src/runtime/execution/jobs/store.ts +3 -4
  313. package/src/runtime/execution/managed-workspace.ts +57 -0
  314. package/src/runtime/execution/process-runtime/check-facade.ts +1 -1
  315. package/src/runtime/execution/process-runtime/check-result-retention.ts +2 -2
  316. package/src/runtime/execution/process-runtime/check-result.ts +105 -1
  317. package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +18 -8
  318. package/src/runtime/execution/process-runtime/command-facade.ts +79 -27
  319. package/src/runtime/execution/process-runtime/gc.ts +15 -2
  320. package/src/runtime/execution/process-runtime/handle-index.ts +176 -0
  321. package/src/runtime/execution/process-runtime/host-command-lane.ts +139 -0
  322. package/src/runtime/execution/process-runtime/index.ts +3 -0
  323. package/src/runtime/execution/process-runtime/lightweight-managed.ts +251 -72
  324. package/src/runtime/execution/process-runtime/persisted-check.ts +3 -3
  325. package/src/runtime/execution/process-runtime/process-runner-entry.ts +47 -5
  326. package/src/runtime/execution/process-runtime/process-scope.ts +160 -0
  327. package/src/runtime/execution/process-runtime/resource-claims.ts +65 -61
  328. package/src/runtime/execution/process-runtime/runtime.ts +35 -2
  329. package/src/runtime/execution/process-runtime/store.ts +30 -2
  330. package/src/runtime/execution/process-runtime/types.ts +6 -1
  331. package/src/runtime/execution/workers/executor.ts +2 -6
  332. package/src/runtime/platform/service-inventory.ts +130 -0
  333. package/src/runtime/platform/service-manager.ts +8 -0
  334. package/src/runtime/plugins/action-application.ts +85 -28
  335. package/src/runtime/plugins/app-store-connect-adapter.ts +38 -14
  336. package/src/runtime/plugins/browser-adapter.ts +757 -34
  337. package/src/runtime/plugins/browser-automation-service.ts +23 -3
  338. package/src/runtime/plugins/browser-macos-bridge.ts +321 -29
  339. package/src/runtime/plugins/browser-manifest-surface.ts +45 -11
  340. package/src/runtime/plugins/browser-native-session-service.ts +63 -13
  341. package/src/runtime/plugins/browser-registration.ts +16 -0
  342. package/src/runtime/plugins/browser-runtime.ts +14 -1
  343. package/src/runtime/plugins/browser-session-authority.ts +2 -2
  344. package/src/runtime/plugins/browser-session-store.ts +46 -76
  345. package/src/runtime/plugins/capability-authorization-grants.ts +258 -62
  346. package/src/runtime/plugins/computer-chatgpt-browser-adapter-installer.ts +219 -0
  347. package/src/runtime/plugins/computer-chatgpt-macos-target.ts +891 -0
  348. package/src/runtime/plugins/computer-registration.ts +222 -11
  349. package/src/runtime/plugins/desktop-operator-external-policy.ts +36 -4
  350. package/src/runtime/plugins/desktop-operator-registration.ts +12 -4
  351. package/src/runtime/plugins/external-adapter.ts +42 -6
  352. package/src/runtime/plugins/external-registration.ts +21 -1
  353. package/src/runtime/plugins/gmail-adapter.ts +23 -2
  354. package/src/runtime/plugins/google-calendar-adapter.ts +2 -2
  355. package/src/runtime/plugins/google-shared.ts +14 -7
  356. package/src/runtime/plugins/google-tasks-adapter.ts +2 -2
  357. package/src/runtime/plugins/ios-adapter.ts +1 -1
  358. package/src/runtime/plugins/lightweight-action.ts +208 -2
  359. package/src/runtime/plugins/local-system-adapter.ts +12 -2
  360. package/src/runtime/plugins/managed-process-adapter.ts +12 -5
  361. package/src/runtime/plugins/plugin-action-sidecar.ts +17 -13
  362. package/src/runtime/plugins/plugin-management-adapter.ts +1 -1
  363. package/src/runtime/plugins/store.ts +602 -428
  364. package/src/runtime/plugins/types.ts +20 -0
  365. package/src/runtime/plugins/xiaohongshu-publish.ts +16 -0
  366. package/src/runtime/projections/invalidation.ts +7 -3
  367. package/src/runtime/projections/materialized-view.ts +80 -36
  368. package/src/runtime/recovery/actions.ts +3 -3
  369. package/src/runtime/recovery/capability-action-application.ts +46 -45
  370. package/src/runtime/recovery/lifecycle-inventory.ts +29 -29
  371. package/src/runtime/recovery/maintenance-executor.ts +374 -123
  372. package/src/runtime/recovery/store.ts +29 -11
  373. package/src/runtime/release/release-coordinator.ts +296 -0
  374. package/src/runtime/release/release-session.ts +716 -0
  375. package/src/runtime/release/release-state-migration.ts +25 -0
  376. package/src/runtime/resources/leases/store.ts +56 -25
  377. package/src/runtime/root/computer-composition.ts +191 -6
  378. package/src/runtime/root/controller-progression-composition.ts +192 -0
  379. package/src/runtime/root/controller-round-composition.ts +20 -1
  380. package/src/runtime/root/deployment-topology.ts +106 -0
  381. package/src/runtime/root/entry.ts +4 -3
  382. package/src/runtime/root/known-good-recovery.ts +184 -0
  383. package/src/runtime/root/local-bridge.ts +0 -1
  384. package/src/runtime/root/mcp-transport.ts +111 -18
  385. package/src/runtime/root/ownership.ts +261 -9
  386. package/src/runtime/root/package-connector-service.ts +105 -19
  387. package/src/runtime/root/package-runtime-release.ts +117 -18
  388. package/src/runtime/root/package-runtime-service.ts +17 -11
  389. package/src/runtime/root/release-execution-canary.ts +44 -12
  390. package/src/runtime/root/release-loader.ts +90 -8
  391. package/src/runtime/root/release-manifest.ts +80 -6
  392. package/src/runtime/root/release-materialize.ts +372 -28
  393. package/src/runtime/root/release-store.ts +395 -36
  394. package/src/runtime/root/runtime-lane.ts +191 -0
  395. package/src/runtime/root/runtime.ts +159 -27
  396. package/src/runtime/root/scheduled-controller-composition.ts +28 -3
  397. package/src/runtime/root/service-runner.ts +2 -2
  398. package/src/runtime/root/service.ts +36 -33
  399. package/src/runtime/root/status.ts +48 -0
  400. package/src/runtime/root/types.ts +32 -3
  401. package/src/runtime/root/workflow-supervisor-composition.ts +493 -0
  402. package/src/runtime/root/workflow-supervisor-runtime.ts +209 -0
  403. package/src/runtime/root/write-fence.ts +50 -2
  404. package/src/runtime/safe-tooling/google-credential-store.ts +76 -21
  405. package/src/runtime/safe-tooling/google-oauth-broker.ts +25 -7
  406. package/src/runtime/safe-tooling/workspace-auth.ts +1 -1
  407. package/src/runtime/shared/bounded-child-supervisor.ts +9 -1
  408. package/src/runtime/shared/process-environment.ts +20 -9
  409. package/src/runtime/shared/response-budget.ts +1 -3
  410. package/src/runtime/standalone-recovery/controller-home-migration.ts +16 -24
  411. package/src/runtime/standalone-recovery/core.ts +3702 -342
  412. package/src/runtime/standalone-recovery/entry.ts +469 -39
  413. package/src/runtime/standalone-recovery/installer.ts +262 -148
  414. package/src/runtime/standalone-recovery/mcp-server.ts +29 -193
  415. package/src/runtime/standalone-recovery/operation-lock.ts +1 -1
  416. package/src/runtime/standalone-recovery/performance.ts +54 -16
  417. package/src/runtime/standalone-recovery/release.ts +53 -5
  418. package/src/runtime/standalone-recovery/service-labels.ts +5 -2
  419. package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +5 -2
  420. package/src/runtime/workflow/schedules/browser-probe.ts +17 -6
  421. package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +10 -3
  422. package/src/runtime/workflow/schedules/engine.ts +138 -172
  423. package/src/runtime/workflow/schedules/work-continuation.ts +44 -5
  424. package/src/runtime/workflows/runtime.ts +15 -19
  425. package/src/testing/test-governance.ts +5 -1
  426. package/supervisor/chatgpt-conversation.ts +23 -0
  427. package/supervisor/client.ts +201 -0
  428. package/supervisor/control-plane.ts +868 -0
  429. package/supervisor/entry.ts +15 -0
  430. package/supervisor/forge-validators.ts +80 -0
  431. package/supervisor/index.ts +5 -0
  432. package/supervisor/native-browser-adapter.ts +786 -0
  433. package/supervisor/native-messaging/host.ts +39 -0
  434. package/supervisor/native-messaging/manifest.ts +26 -0
  435. package/supervisor/native-messaging/protocol.ts +27 -0
  436. package/supervisor/paths.ts +18 -0
  437. package/supervisor/protocol.ts +202 -0
  438. package/supervisor/server.ts +404 -0
  439. package/supervisor/store.ts +1451 -0
  440. package/supervisor/tsconfig.json +8 -0
  441. package/supervisor/types.ts +255 -0
  442. package/adapters/chatgpt/controller-host.ts +0 -119
  443. package/adapters/mcp/controller-round-compatibility.ts +0 -184
  444. package/adapters/mcp/frozen-client-semantic-compatibility.ts +0 -292
  445. package/adapters/mcp/runtime-gateway/work-compat-adapter.ts +0 -502
  446. package/packages/kernel/progression/api/index.ts +0 -2
  447. package/packages/kernel/progression/application/projector.ts +0 -211
  448. package/packages/kernel/progression/domain/types.ts +0 -116
  449. package/packages/kernel/progression/index.ts +0 -1
  450. package/packages/kernel/scheduler/application/continuation-service.ts +0 -212
  451. package/packages/kernel/scheduler/domain/continuation.ts +0 -38
  452. package/packages/kernel/scheduler/infrastructure/continuation-dispatch-store.ts +0 -38
  453. package/packages/kernel/work/domain/admission-policy.ts +0 -34
  454. package/scripts/benchmark-background-check-overlap.ts +0 -228
  455. package/scripts/benchmark-computer-hotpath.ts +0 -255
  456. package/scripts/benchmark-controller-hotpath.ts +0 -212
  457. package/scripts/benchmark-controller-round2.ts +0 -191
  458. package/scripts/benchmark-ios-agent-device.ts +0 -511
  459. package/scripts/benchmark-mcp-host.sh +0 -117
  460. package/scripts/benchmark-mcp-transport.ts +0 -169
  461. package/scripts/benchmark-operational-memory-activation.ts +0 -235
  462. package/scripts/benchmark-operational-shadow.ts +0 -28
  463. package/scripts/benchmark-quality-harness.ts +0 -146
  464. package/scripts/benchmark-route-session-concurrency.ts +0 -915
  465. package/scripts/benchmark-thin-harness-gateway-ab.ts +0 -632
  466. package/scripts/benchmark-thin-harness-mcp-e2e.ts +0 -498
  467. package/scripts/benchmark-thin-harness.ts +0 -251
  468. package/scripts/benchmark-typescript-navigation.ts +0 -186
  469. package/scripts/benchmark-work-efficiency.ts +0 -334
  470. package/scripts/build-controller-ui.ts +0 -28
  471. package/scripts/check-npm-release.sh +0 -32
  472. package/scripts/check-public-release-surface.sh +0 -19
  473. package/scripts/check-release-published.sh +0 -57
  474. package/scripts/check-release-readiness.sh +0 -37
  475. package/scripts/check-release-version.mjs +0 -74
  476. package/scripts/check-tarball-install-smoke.sh +0 -150
  477. package/scripts/package-source-archive.sh +0 -147
  478. package/scripts/public-release-files.txt +0 -39
  479. package/scripts/public-release.ts +0 -174
  480. package/scripts/publish-release-tarball.sh +0 -27
  481. package/scripts/route-nl-vs-ts-eval.ts +0 -679
  482. package/scripts/stage-runtime-release.ts +0 -44
  483. package/src/cli/controller/progress.ts +0 -656
  484. package/src/cli/controller/work-mode.ts +0 -181
  485. package/src/cli/local-bridge/console-assets.ts +0 -17
  486. package/src/cli/local-bridge/dashboard.ts +0 -17
  487. package/src/cli/local-bridge/frontend/src/App.tsx +0 -10
  488. package/src/cli/local-bridge/frontend/src/components/Button.tsx +0 -1
  489. package/src/cli/local-bridge/frontend/src/components/DetailPane.tsx +0 -3
  490. package/src/cli/local-bridge/frontend/src/components/SearchField.tsx +0 -1
  491. package/src/cli/local-bridge/frontend/src/components/SectionHeader.tsx +0 -1
  492. package/src/cli/local-bridge/frontend/src/components/Segmented.tsx +0 -1
  493. package/src/cli/local-bridge/frontend/src/components/StatusText.tsx +0 -3
  494. package/src/cli/local-bridge/frontend/src/design/icons.tsx +0 -11
  495. package/src/cli/local-bridge/frontend/src/design/tokens.css +0 -8
  496. package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +0 -153
  497. package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +0 -37
  498. package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +0 -183
  499. package/src/cli/local-bridge/frontend/src/features/repositories/RepositoriesView.tsx +0 -2
  500. package/src/cli/local-bridge/frontend/src/features/system/SystemView.tsx +0 -2
  501. package/src/cli/local-bridge/frontend/src/features/work/WorkView.tsx +0 -4
  502. package/src/cli/local-bridge/frontend/src/lib/api.ts +0 -30
  503. package/src/cli/local-bridge/frontend/src/lib/format.ts +0 -4
  504. package/src/cli/local-bridge/frontend/src/lib/routes.ts +0 -7
  505. package/src/cli/local-bridge/frontend/src/main.tsx +0 -1
  506. package/src/cli/local-bridge/frontend/src/shell/AppShell.tsx +0 -1
  507. package/src/cli/local-bridge/frontend/src/shell/CommandBar.tsx +0 -2
  508. package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +0 -4
  509. package/src/cli/local-bridge/frontend/src/styles.css +0 -28
  510. package/src/cli/local-bridge/frontend/src/types.ts +0 -15
  511. package/src/cli/local-bridge/frontend/src/vite-env.d.ts +0 -1
  512. package/src/cli/local-bridge/frontend/vite.config.ts +0 -27
  513. package/src/cli/local-bridge/ui-dist/app.css +0 -1
  514. package/src/cli/local-bridge/ui-dist/app.js +0 -11228
  515. package/src/runtime/control-plane/execution/content-equivalent-commit-authority.ts +0 -169
  516. package/src/runtime/control-plane/execution/direct-canonical-work-reconciliation.ts +0 -85
  517. package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +0 -655
  518. package/src/runtime/control-plane/execution/work-finalization-service.ts +0 -2850
  519. package/src/runtime/control-plane/execution/work-path-scope.ts +0 -37
  520. package/src/runtime/control-plane/execution/work-task-receipt.ts +0 -468
  521. package/src/runtime/control-plane/facade/controller-round-relay.ts +0 -3
  522. package/src/runtime/control-plane/facade/work-admission-policy.ts +0 -142
  523. package/src/runtime/control-plane/facade/work-implementation-review.ts +0 -2
  524. package/src/runtime/control-plane/facade/work-state-machine.ts +0 -2
  525. package/src/runtime/control-plane/facade/work-task-projection.ts +0 -66
  526. package/src/runtime/control-plane/routing/index.ts +0 -1
  527. package/src/runtime/control-plane/routing/route-policy.ts +0 -401
  528. package/src/runtime/control-plane/routing/workspace-admission.ts +0 -70
@@ -1,11 +1,13 @@
1
1
  import { createHash, randomUUID } from 'crypto';
2
2
  import { createRequire } from 'module';
3
- import { chmodSync, copyFileSync, cpSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from 'fs';
3
+ import { chmodSync, copyFileSync, cpSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, symlinkSync, writeFileSync } from 'fs';
4
+ import { tmpdir } from 'os';
4
5
  import { dirname, join, relative, resolve } from 'path';
5
6
  import { runProcess } from '../../effects/process-runner';
6
7
  import { resolveBunExecutable } from '../shared/process-environment';
8
+ import { assertStorageHeadroom } from '../shared/storage-capacity';
7
9
  import { CONTROL_PLANE_SCHEMA_VERSION } from '../control-plane/persistence/sqlite-store';
8
- import { loadRuntimeReleaseManifest, requireCompleteCompiledRuntimeReleaseManifest } from './release-manifest';
10
+ import { assertRuntimeReleaseExecutionSurface, loadRuntimeReleaseManifest, requireCompleteCompiledRuntimeReleaseManifest } from './release-manifest';
9
11
  import { assertRuntimeReleaseExecutionCanaries, type RuntimeReleaseExecutionCanaryCommand } from './release-execution-canary';
10
12
  export { assertRuntimeReleaseExecutionCanaries, type RuntimeReleaseExecutionCanaryDependencies } from './release-execution-canary';
11
13
  import { packageRuntimeFileIndex, stagePackageRuntimeSnapshot } from './package-runtime-release';
@@ -34,11 +36,16 @@ export interface StagedRuntimeRelease {
34
36
  releaseId: string;
35
37
  artifactIdentity: string;
36
38
  runtimeBundleArtifactIdentity?: string;
39
+ runtimeInterpreterArtifactIdentity?: string;
37
40
  diagnosticArtifactIdentity?: string;
41
+ connectorArtifactIdentity?: string;
38
42
  browserNodeBridgeArtifactIdentity?: string;
39
43
  browserHandoffArtifactIdentity?: string;
44
+ workflowSupervisorNativeHostArtifactIdentity?: string;
40
45
  processRunnerArtifactIdentity?: string;
41
46
  checkRunnerArtifactIdentity?: string;
47
+ typescriptNavigationArtifactIdentity?: string;
48
+ contextPackArtifactIdentity?: string;
42
49
  schedulerWorkerArtifactIdentity?: string;
43
50
  periodicCleanupArtifactIdentity?: string;
44
51
  pluginActionSidecarArtifactIdentity?: string;
@@ -61,6 +68,7 @@ export interface RuntimeReleaseMaterializerDependencies {
61
68
  uuid?: () => string;
62
69
  compileBinary?: (input: { sourceRoot: string; outputPath: string; entryPath?: string }) => { ok: boolean; stderr?: string; stdout?: string; error?: string };
63
70
  bundleRuntime?: (input: { sourceRoot: string; outputPath: string; entryPath: string }) => { ok: boolean; stderr?: string; stdout?: string; error?: string };
71
+ materializeRuntimeInterpreter?: (input: { sourceRoot: string; outputPath: string }) => { ok: boolean; stderr?: string; stdout?: string; error?: string };
64
72
  bundleNodeHost?: (input: { sourceRoot: string; outputPath: string; entryPath: string }) => { ok: boolean; stderr?: string; stdout?: string; error?: string };
65
73
  bundleProcessRunner?: (input: { sourceRoot: string; outputPath: string; entryPath: string }) => { ok: boolean; stderr?: string; stdout?: string; error?: string };
66
74
  materializeCodeGraphRuntime?: (input: {
@@ -89,6 +97,7 @@ export interface CandidateRuntimeReleaseStagerDependencies {
89
97
  bunExecutable: string;
90
98
  scriptPath: string;
91
99
  sourceRoot: string;
100
+ dependencyRoot: string;
92
101
  controllerHome: string;
93
102
  expectedHead: string;
94
103
  sourceRepositoryId: string;
@@ -102,6 +111,61 @@ function gitText(root: string, args: string[]): string {
102
111
  return result.stdout.trim();
103
112
  }
104
113
 
114
+ /**
115
+ * Materialize one exact tracked Git revision into a detached temporary worktree.
116
+ * The mutable source checkout remains only the object/dependency provider and may
117
+ * advance while the callback runs. Lifecycle/Runtime authority is untouched.
118
+ */
119
+ export function withRuntimeReleaseSourceSnapshot<T>(input: {
120
+ sourceRoot: string;
121
+ sourceRevision: string;
122
+ }, operation: (snapshotRoot: string) => T): T {
123
+ const sourceRoot = resolve(input.sourceRoot);
124
+ const requestedRevision = input.sourceRevision.trim();
125
+ if (!/^[a-f0-9]{40}$/i.test(requestedRevision)) throw new Error('RUNTIME_RELEASE_SOURCE_REVISION_INVALID');
126
+ const resolvedRevision = gitText(sourceRoot, ['rev-parse', '--verify', `${requestedRevision}^{commit}`]);
127
+ if (resolvedRevision !== requestedRevision) throw new Error('RUNTIME_RELEASE_SOURCE_REVISION_MISMATCH');
128
+ // Release materialization is Runtime-owned temporary state, not repository
129
+ // workspace state. Keeping the detached worktree outside sourceRoot prevents
130
+ // Forge's own immutable-source snapshot from perturbing repository status or
131
+ // workspace fingerprints while release validation is running.
132
+ const snapshotContainer = mkdtempSync(join(tmpdir(), `forge-runtime-release-source-${process.pid}-`));
133
+ const snapshotRoot = join(snapshotContainer, `${requestedRevision}-${randomUUID().slice(0, 8)}`);
134
+ const materialized = runProcess('git', ['-C', sourceRoot, 'worktree', 'add', '--detach', '--force', snapshotRoot, requestedRevision], {
135
+ timeoutMs: 60_000,
136
+ maxOutputBytes: 128 * 1024,
137
+ });
138
+ if (!materialized.ok) {
139
+ rmSync(snapshotContainer, { recursive: true, force: true });
140
+ runProcess('git', ['-C', sourceRoot, 'worktree', 'prune'], { timeoutMs: 30_000, maxOutputBytes: 64 * 1024 });
141
+ throw new Error(`RUNTIME_RELEASE_SOURCE_SNAPSHOT_FAILED: ${materialized.stderr || materialized.stdout || materialized.error}`.slice(0, 2_000));
142
+ }
143
+ try {
144
+ const sourceDependencies = join(sourceRoot, 'node_modules');
145
+ if (existsSync(sourceDependencies)) {
146
+ const snapshotDependencies = join(snapshotRoot, 'node_modules');
147
+ symlinkSync(realpathSync(sourceDependencies), snapshotDependencies, process.platform === 'win32' ? 'junction' : 'dir');
148
+ }
149
+ if (gitText(snapshotRoot, ['rev-parse', '--verify', 'HEAD']) !== requestedRevision) {
150
+ throw new Error('RUNTIME_RELEASE_SOURCE_SNAPSHOT_REVISION_MISMATCH');
151
+ }
152
+ if (gitText(snapshotRoot, ['status', '--porcelain=v1', '--untracked-files=no'])) {
153
+ throw new Error('RUNTIME_RELEASE_SOURCE_SNAPSHOT_DIRTY');
154
+ }
155
+ return operation(snapshotRoot);
156
+ } finally {
157
+ const removed = runProcess('git', ['-C', sourceRoot, 'worktree', 'remove', '--force', snapshotRoot], {
158
+ timeoutMs: 60_000,
159
+ maxOutputBytes: 128 * 1024,
160
+ });
161
+ if (!removed.ok) {
162
+ rmSync(snapshotRoot, { recursive: true, force: true });
163
+ }
164
+ runProcess('git', ['-C', sourceRoot, 'worktree', 'prune'], { timeoutMs: 30_000, maxOutputBytes: 64 * 1024 });
165
+ rmSync(snapshotContainer, { recursive: true, force: true });
166
+ }
167
+ }
168
+
105
169
  function sha256(path: string): string {
106
170
  return createHash('sha256').update(readFileSync(path)).digest('hex');
107
171
  }
@@ -164,6 +228,10 @@ function inspectMacOSRuntimeCodeSigning(executable: string): MacOSRuntimeCodeSig
164
228
  return parseMacOSRuntimeCodeSigning({ identifier, teamIdentifier, authority, designatedRequirement }, 'RUNTIME_RELEASE_MACOS_SIGNATURE_INVALID')!;
165
229
  }
166
230
 
231
+ export function macOSRuntimeSigningMayRetryWithoutTimestamp(detail: string): boolean {
232
+ return /(?:^|\n).*timestamp service is not available\.?\s*$/im.test(detail);
233
+ }
234
+
167
235
  function defaultSignMacOSRuntime(input: { executable: string; controllerHome: string }): MacOSRuntimeCodeSigning {
168
236
  const identities = runProcess('security', ['find-identity', '-v', '-p', 'codesigning'], { timeoutMs: 30_000, maxOutputBytes: 128 * 1024 });
169
237
  if (!identities.ok) throw new Error(`RUNTIME_RELEASE_MACOS_SIGNING_IDENTITY_LOOKUP_FAILED: ${identities.stderr || identities.stdout || identities.error}`.slice(0, 2_000));
@@ -186,9 +254,16 @@ function defaultSignMacOSRuntime(input: { executable: string; controllerHome: st
186
254
  selected = eligible[0];
187
255
  }
188
256
  if (expectedTeam && selected.teamIdentifier !== expectedTeam) throw new Error('RUNTIME_RELEASE_MACOS_SIGNING_TEAM_CHANGED');
189
- const signed = runProcess('codesign', [
190
- '--force', '--sign', selected.hash, '--identifier', FORGE_MACOS_RUNTIME_SIGNING_IDENTIFIER, '--options', 'runtime', input.executable,
191
- ], { timeoutMs: 120_000, maxOutputBytes: 128 * 1024 });
257
+ const signingArgs = [
258
+ '--force', '--sign', selected.hash, '--identifier', FORGE_MACOS_RUNTIME_SIGNING_IDENTIFIER, '--options', 'runtime',
259
+ ];
260
+ let signed = runProcess('codesign', [...signingArgs, input.executable], { timeoutMs: 120_000, maxOutputBytes: 128 * 1024 });
261
+ if (!signed.ok) {
262
+ const detail = `${signed.stderr ?? ''}\n${signed.stdout ?? ''}\n${signed.error ?? ''}`;
263
+ if (macOSRuntimeSigningMayRetryWithoutTimestamp(detail)) {
264
+ signed = runProcess('codesign', [...signingArgs, '--timestamp=none', input.executable], { timeoutMs: 120_000, maxOutputBytes: 128 * 1024 });
265
+ }
266
+ }
192
267
  if (!signed.ok) throw new Error(`RUNTIME_RELEASE_MACOS_SIGNING_FAILED: ${signed.stderr || signed.stdout || signed.error}`.slice(0, 2_000));
193
268
  const inspected = inspectMacOSRuntimeCodeSigning(input.executable);
194
269
  if (inspected.teamIdentifier !== selected.teamIdentifier) throw new Error('RUNTIME_RELEASE_MACOS_SIGNING_TEAM_MISMATCH');
@@ -258,10 +333,12 @@ function parseCandidateStageReceipt(stdout: string): CandidateRuntimeStageReceip
258
333
  export function stageRuntimeReleaseFromCandidateSource(input: {
259
334
  controllerHome: string;
260
335
  sourceRoot: string;
336
+ dependencyRoot?: string;
261
337
  sourceRepositoryId: string;
262
338
  }, dependencies: CandidateRuntimeReleaseStagerDependencies = {}): StagedRuntimeRelease {
263
339
  const controllerHome = resolve(input.controllerHome);
264
340
  const sourceRoot = resolve(input.sourceRoot);
341
+ const dependencyRoot = resolve(input.dependencyRoot ?? input.sourceRoot);
265
342
  const sourceRepositoryId = input.sourceRepositoryId.trim();
266
343
  if (!sourceRepositoryId) throw new Error('RUNTIME_RELEASE_SOURCE_REPOSITORY_ID_REQUIRED');
267
344
  const expectedHead = gitText(sourceRoot, ['rev-parse', '--verify', 'HEAD']);
@@ -279,10 +356,11 @@ export function stageRuntimeReleaseFromCandidateSource(input: {
279
356
  request.scriptPath,
280
357
  '--controller-home', request.controllerHome,
281
358
  '--source-root', request.sourceRoot,
359
+ '--dependency-root', request.dependencyRoot,
282
360
  '--expected-head', request.expectedHead,
283
361
  '--source-repository-id', request.sourceRepositoryId,
284
362
  ], { cwd: request.sourceRoot, timeoutMs: 600_000, maxOutputBytes: 512 * 1024 }));
285
- const executed = runCandidateStager({ bunExecutable, scriptPath, sourceRoot, controllerHome, expectedHead, sourceRepositoryId });
363
+ const executed = runCandidateStager({ bunExecutable, scriptPath, sourceRoot, dependencyRoot, controllerHome, expectedHead, sourceRepositoryId });
286
364
  if (!executed.ok) {
287
365
  throw new Error(`RUNTIME_RELEASE_CANDIDATE_STAGE_FAILED: ${executed.stderr || executed.stdout || executed.error}`.slice(0, 2_000));
288
366
  }
@@ -360,9 +438,12 @@ export function stageRuntimeReleaseFromCandidateSource(input: {
360
438
  releaseId: receipt.releaseId,
361
439
  artifactIdentity: receipt.artifactIdentity,
362
440
  runtimeBundleArtifactIdentity: manifest.runtimeBundleArtifactIdentity,
441
+ runtimeInterpreterArtifactIdentity: manifest.runtimeInterpreterArtifactIdentity,
363
442
  diagnosticArtifactIdentity: manifest.diagnosticArtifactIdentity,
443
+ connectorArtifactIdentity: manifest.connectorArtifactIdentity,
364
444
  browserNodeBridgeArtifactIdentity: manifest.browserNodeBridgeArtifactIdentity,
365
445
  browserHandoffArtifactIdentity: manifest.browserHandoffArtifactIdentity,
446
+ workflowSupervisorNativeHostArtifactIdentity: manifest.workflowSupervisorNativeHostArtifactIdentity,
366
447
  processRunnerArtifactIdentity: manifest.processRunnerArtifactIdentity,
367
448
  checkRunnerArtifactIdentity: manifest.checkRunnerArtifactIdentity,
368
449
  schedulerWorkerArtifactIdentity: manifest.schedulerWorkerArtifactIdentity,
@@ -396,6 +477,31 @@ function defaultCompileBinary(input: { sourceRoot: string; outputPath: string; e
396
477
  ], { cwd: input.sourceRoot, timeoutMs: 300_000, maxOutputBytes: 512 * 1024 });
397
478
  }
398
479
 
480
+ function defaultMaterializeRuntimeInterpreter(input: { sourceRoot: string; outputPath: string }): { ok: boolean; stderr?: string; stdout?: string; error?: string } {
481
+ const configured = process.env.FORGE_BUN_BIN?.trim();
482
+ const bun = configured || resolveBunExecutable(process.execPath, process.env);
483
+ const probe = runProcess(bun, ['-e', 'process.stdout.write(process.execPath)'], {
484
+ cwd: input.sourceRoot,
485
+ timeoutMs: 15_000,
486
+ maxOutputBytes: 16 * 1024,
487
+ });
488
+ if (!probe.ok) return probe;
489
+ try {
490
+ const reported = probe.stdout.trim();
491
+ if (!reported) return { ok: false, error: 'Bun did not report process.execPath' };
492
+ const source = realpathSync(resolve(reported));
493
+ const status = lstatSync(source);
494
+ if (status.isSymbolicLink() || !status.isFile() || (status.mode & 0o111) === 0) {
495
+ return { ok: false, error: `resolved Bun interpreter is not a regular executable: ${source}` };
496
+ }
497
+ copyFileSync(source, input.outputPath);
498
+ chmodSync(input.outputPath, 0o700);
499
+ return { ok: true };
500
+ } catch (error) {
501
+ return { ok: false, error: error instanceof Error ? error.message : String(error) };
502
+ }
503
+ }
504
+
399
505
  function defaultBundleRuntimeScript(input: { sourceRoot: string; outputPath: string; entryPath: string }): { ok: boolean; stderr?: string; stdout?: string; error?: string } {
400
506
  const configured = process.env.FORGE_BUN_BIN?.trim();
401
507
  const bun = configured || resolveBunExecutable(process.execPath, process.env);
@@ -449,9 +555,11 @@ function defaultMaterializeCodeGraphRuntime(input: {
449
555
  export function stageRuntimeRelease(input: {
450
556
  controllerHome: string;
451
557
  sourceRoot: string;
558
+ dependencyRoot?: string;
452
559
  sourceRepositoryId?: string;
453
560
  }, dependencies: RuntimeReleaseMaterializerDependencies = {}): StagedRuntimeRelease {
454
561
  const sourceRoot = resolve(input.sourceRoot);
562
+ const dependencyRoot = resolve(input.dependencyRoot ?? input.sourceRoot);
455
563
  const sourceRepositoryId = input.sourceRepositoryId?.trim();
456
564
  if (input.sourceRepositoryId !== undefined && !sourceRepositoryId) throw new Error('RUNTIME_RELEASE_SOURCE_REPOSITORY_ID_INVALID');
457
565
  const sourceCommit = gitText(sourceRoot, ['rev-parse', '--verify', 'HEAD']);
@@ -472,6 +580,7 @@ export function stageRuntimeRelease(input: {
472
580
  mkdirSync(staging, { recursive: true, mode: 0o700 });
473
581
  try {
474
582
  const compileBinary = dependencies.compileBinary ?? defaultCompileBinary;
583
+ const platform = dependencies.platform ?? process.platform;
475
584
  const runtimeBundleEntrypoint = 'forge-runtime-bundle.js' as const;
476
585
  const runtimeBundlePath = join(staging, runtimeBundleEntrypoint);
477
586
  const runtimeBundle = (dependencies.bundleRuntime ?? defaultBundleRuntimeScript)({
@@ -485,6 +594,20 @@ export function stageRuntimeRelease(input: {
485
594
  chmodSync(runtimeBundlePath, 0o600);
486
595
  const runtimeBundleArtifactIdentity = `sha256:${sha256(runtimeBundlePath)}`;
487
596
 
597
+ const runtimeInterpreterEntrypoint = platform === 'win32'
598
+ ? 'forge-runtime-bun.exe' as const
599
+ : 'forge-runtime-bun' as const;
600
+ const runtimeInterpreterPath = join(staging, runtimeInterpreterEntrypoint);
601
+ const runtimeInterpreter = (dependencies.materializeRuntimeInterpreter ?? defaultMaterializeRuntimeInterpreter)({
602
+ sourceRoot,
603
+ outputPath: runtimeInterpreterPath,
604
+ });
605
+ if (!runtimeInterpreter.ok) {
606
+ throw new Error(`RUNTIME_RELEASE_INTERPRETER_BUILD_FAILED: ${runtimeInterpreter.stderr || runtimeInterpreter.stdout || runtimeInterpreter.error}`.slice(0, 2_000));
607
+ }
608
+ chmodSync(runtimeInterpreterPath, 0o700);
609
+ const runtimeInterpreterArtifactIdentity = `sha256:${sha256(runtimeInterpreterPath)}`;
610
+
488
611
  const executable = join(staging, 'forge-runtime');
489
612
  const compile = compileBinary({
490
613
  sourceRoot,
@@ -495,7 +618,6 @@ export function stageRuntimeRelease(input: {
495
618
  throw new Error(`RUNTIME_RELEASE_BUILD_FAILED: ${compile.stderr || compile.stdout || compile.error}`.slice(0, 2_000));
496
619
  }
497
620
  chmodSync(executable, 0o700);
498
- const platform = dependencies.platform ?? process.platform;
499
621
  const macosCodeSigning = platform === 'darwin'
500
622
  ? (dependencies.signMacOSRuntime ?? defaultSignMacOSRuntime)({ executable, controllerHome: resolve(input.controllerHome) })
501
623
  : undefined;
@@ -517,6 +639,19 @@ export function stageRuntimeRelease(input: {
517
639
  chmodSync(diagnosticExecutable, 0o700);
518
640
  const diagnosticArtifactIdentity = `sha256:${sha256(diagnosticExecutable)}`;
519
641
 
642
+ const connectorEntrypoint = 'forge-mcp-gateway' as const;
643
+ const connectorPath = join(staging, connectorEntrypoint);
644
+ const connectorCompile = compileBinary({
645
+ sourceRoot,
646
+ outputPath: connectorPath,
647
+ entryPath: join(sourceRoot, 'src/cli/index.ts'),
648
+ });
649
+ if (!connectorCompile.ok) {
650
+ throw new Error(`RUNTIME_RELEASE_CONNECTOR_BUILD_FAILED: ${connectorCompile.stderr || connectorCompile.stdout || connectorCompile.error}`.slice(0, 2_000));
651
+ }
652
+ chmodSync(connectorPath, 0o700);
653
+ const connectorArtifactIdentity = `sha256:${sha256(connectorPath)}`;
654
+
520
655
  const browserNodeBridgeEntrypoint = 'browser-node-bridge-host.js' as const;
521
656
  const browserNodeBridgePath = join(staging, browserNodeBridgeEntrypoint);
522
657
  const bundleNodeHost = dependencies.bundleNodeHost ?? defaultBundleNodeScript;
@@ -544,6 +679,19 @@ export function stageRuntimeRelease(input: {
544
679
  chmodSync(browserHandoffPath, 0o700);
545
680
  const browserHandoffArtifactIdentity = `sha256:${sha256(browserHandoffPath)}`;
546
681
 
682
+ const workflowSupervisorNativeHostEntrypoint = 'forge-workflow-supervisor-native-host' as const;
683
+ const workflowSupervisorNativeHostPath = join(staging, workflowSupervisorNativeHostEntrypoint);
684
+ const workflowSupervisorNativeHostCompile = compileBinary({
685
+ sourceRoot,
686
+ outputPath: workflowSupervisorNativeHostPath,
687
+ entryPath: join(sourceRoot, 'supervisor', 'native-messaging', 'host.ts'),
688
+ });
689
+ if (!workflowSupervisorNativeHostCompile.ok) {
690
+ throw new Error(`RUNTIME_RELEASE_WORKFLOW_SUPERVISOR_NATIVE_HOST_BUILD_FAILED: ${workflowSupervisorNativeHostCompile.stderr || workflowSupervisorNativeHostCompile.stdout || workflowSupervisorNativeHostCompile.error}`.slice(0, 2_000));
691
+ }
692
+ chmodSync(workflowSupervisorNativeHostPath, 0o700);
693
+ const workflowSupervisorNativeHostArtifactIdentity = `sha256:${sha256(workflowSupervisorNativeHostPath)}`;
694
+
547
695
  const processRunnerEntrypoint = 'process-runner.js' as const;
548
696
  const processRunnerPath = join(staging, processRunnerEntrypoint);
549
697
  // Process Runner is part of the immutable execution surface and must not
@@ -576,6 +724,32 @@ export function stageRuntimeRelease(input: {
576
724
  chmodSync(checkRunnerPath, 0o700);
577
725
  const checkRunnerArtifactIdentity = `sha256:${sha256(checkRunnerPath)}`;
578
726
 
727
+ const typescriptNavigationEntrypoint = 'forge-typescript-navigation' as const;
728
+ const typescriptNavigationPath = join(staging, typescriptNavigationEntrypoint);
729
+ const typescriptNavigationCompile = compileBinary({
730
+ sourceRoot,
731
+ outputPath: typescriptNavigationPath,
732
+ entryPath: join(sourceRoot, 'adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts'),
733
+ });
734
+ if (!typescriptNavigationCompile.ok) {
735
+ throw new Error(`RUNTIME_RELEASE_TYPESCRIPT_NAVIGATION_BUILD_FAILED: ${typescriptNavigationCompile.stderr || typescriptNavigationCompile.stdout || typescriptNavigationCompile.error}`.slice(0, 2_000));
736
+ }
737
+ chmodSync(typescriptNavigationPath, 0o700);
738
+ const typescriptNavigationArtifactIdentity = `sha256:${sha256(typescriptNavigationPath)}`;
739
+
740
+ const contextPackEntrypoint = 'forge-context-pack' as const;
741
+ const contextPackPath = join(staging, contextPackEntrypoint);
742
+ const contextPackCompile = compileBinary({
743
+ sourceRoot,
744
+ outputPath: contextPackPath,
745
+ entryPath: join(sourceRoot, 'adapters/mcp/runtime-gateway/context-pack-sidecar.ts'),
746
+ });
747
+ if (!contextPackCompile.ok) {
748
+ throw new Error(`RUNTIME_RELEASE_CONTEXT_PACK_BUILD_FAILED: ${contextPackCompile.stderr || contextPackCompile.stdout || contextPackCompile.error}`.slice(0, 2_000));
749
+ }
750
+ chmodSync(contextPackPath, 0o700);
751
+ const contextPackArtifactIdentity = `sha256:${sha256(contextPackPath)}`;
752
+
579
753
  const schedulerWorkerEntrypoint = 'forge-scheduler-worker' as const;
580
754
  const schedulerWorkerPath = join(staging, schedulerWorkerEntrypoint);
581
755
  const schedulerWorkerCompile = compileBinary({
@@ -646,25 +820,17 @@ export function stageRuntimeRelease(input: {
646
820
  const codeGraphSidecarArtifactIdentity = `sha256:${sha256(codeGraphSidecarPath)}`;
647
821
  const codeGraphLibraryArtifactIdentity = `sha256:${sha256Directory(codeGraphLibraryPath)}`;
648
822
 
649
- const controllerUiRoot = 'ui-dist' as const;
650
- const sourceControllerUiPath = join(sourceRoot, 'src', 'cli', 'local-bridge', controllerUiRoot);
651
- const sourceControllerUiJs = join(sourceControllerUiPath, 'app.js');
652
- const sourceControllerUiCss = join(sourceControllerUiPath, 'app.css');
653
- if (!existsSync(sourceControllerUiJs) || !existsSync(sourceControllerUiCss)) {
654
- throw new Error(`RUNTIME_RELEASE_CONTROLLER_UI_SOURCE_MISSING: ${sourceControllerUiPath}`);
655
- }
656
- const controllerUiPath = join(staging, controllerUiRoot);
657
- cpSync(sourceControllerUiPath, controllerUiPath, { recursive: true, force: false });
658
- const controllerUiArtifactIdentity = `sha256:${sha256Directory(controllerUiPath)}`;
659
-
660
- // The persistent OAuth/Connector is source-backed even when the primary
661
- // Runtime itself is compiled. Co-locate one immutable package snapshot in
662
- // the same release so standalone Recovery can bind the Connector to the
663
- // exact active release instead of retaining an older package release.
823
+ // Keep the source-backed package projection during the Recovery migration.
824
+ // The active standalone Recovery release can predate the compiled Connector
825
+ // sidecar and still rebind the primary Connector through package/src/cli.
826
+ // Removing that surface here makes a candidate pass isolated Runtime
827
+ // canaries but fail the real cutover with missing CLI command modules. Once
828
+ // every supported Recovery release launches forge-mcp-gateway, this
829
+ // compatibility projection can be removed together with the fallback.
664
830
  const packageRoot = 'package' as const;
665
831
  const packagePath = join(staging, packageRoot);
666
- const packageRecords = packageRuntimeFileIndex(sourceRoot);
667
- stagePackageRuntimeSnapshot(sourceRoot, packagePath, packageRecords);
832
+ const packageRecords = packageRuntimeFileIndex(sourceRoot, dependencyRoot);
833
+ stagePackageRuntimeSnapshot(sourceRoot, packagePath, packageRecords, dependencyRoot);
668
834
  const packageArtifactIdentity = `sha256:${sha256Directory(packagePath)}`;
669
835
 
670
836
  const manifest = {
@@ -675,17 +841,27 @@ export function stageRuntimeRelease(input: {
675
841
  executionMode: 'standalone-binary',
676
842
  runtimeBundleEntrypoint,
677
843
  runtimeBundleArtifactIdentity,
844
+ runtimeInterpreterEntrypoint,
845
+ runtimeInterpreterArtifactIdentity,
678
846
  ...(normalizedMacOSCodeSigning ? { macosCodeSigning: normalizedMacOSCodeSigning } : {}),
679
847
  diagnosticEntrypoint: 'forge-cli',
680
848
  diagnosticArtifactIdentity,
849
+ connectorEntrypoint,
850
+ connectorArtifactIdentity,
681
851
  browserNodeBridgeEntrypoint,
682
852
  browserNodeBridgeArtifactIdentity,
683
853
  browserHandoffEntrypoint,
684
854
  browserHandoffArtifactIdentity,
855
+ workflowSupervisorNativeHostEntrypoint,
856
+ workflowSupervisorNativeHostArtifactIdentity,
685
857
  processRunnerEntrypoint,
686
858
  processRunnerArtifactIdentity,
687
859
  checkRunnerEntrypoint,
688
860
  checkRunnerArtifactIdentity,
861
+ typescriptNavigationEntrypoint,
862
+ typescriptNavigationArtifactIdentity,
863
+ contextPackEntrypoint,
864
+ contextPackArtifactIdentity,
689
865
  schedulerWorkerEntrypoint,
690
866
  schedulerWorkerArtifactIdentity,
691
867
  periodicCleanupEntrypoint,
@@ -702,11 +878,9 @@ export function stageRuntimeRelease(input: {
702
878
  codeGraphLibraryArtifactIdentity,
703
879
  packageRoot,
704
880
  packageArtifactIdentity,
705
- controllerUiRoot,
706
- controllerUiArtifactIdentity,
707
881
  arguments: [],
708
882
  configurationSchemaVersion: 1,
709
- controllerHome: resolve(input.controllerHome),
883
+ deploymentScope: 'portable',
710
884
  databaseSchemaCompatibility: {
711
885
  minimum: CONTROL_PLANE_SCHEMA_VERSION,
712
886
  maximum: CONTROL_PLANE_SCHEMA_VERSION,
@@ -728,12 +902,17 @@ export function stageRuntimeRelease(input: {
728
902
  releaseId,
729
903
  artifactIdentity,
730
904
  runtimeBundleArtifactIdentity,
905
+ runtimeInterpreterArtifactIdentity,
731
906
  ...(normalizedMacOSCodeSigning ? { macosCodeSigning: normalizedMacOSCodeSigning } : {}),
732
907
  diagnosticArtifactIdentity,
908
+ connectorArtifactIdentity,
733
909
  browserNodeBridgeArtifactIdentity,
734
910
  browserHandoffArtifactIdentity,
911
+ workflowSupervisorNativeHostArtifactIdentity,
735
912
  processRunnerArtifactIdentity,
736
913
  checkRunnerArtifactIdentity,
914
+ typescriptNavigationArtifactIdentity,
915
+ contextPackArtifactIdentity,
737
916
  schedulerWorkerArtifactIdentity,
738
917
  periodicCleanupArtifactIdentity,
739
918
  pluginActionSidecarArtifactIdentity,
@@ -742,7 +921,6 @@ export function stageRuntimeRelease(input: {
742
921
  codeGraphSidecarArtifactIdentity,
743
922
  codeGraphLibraryArtifactIdentity,
744
923
  packageArtifactIdentity,
745
- controllerUiArtifactIdentity,
746
924
  manifestSha256: createHash('sha256').update(`${JSON.stringify(manifest, null, 2)}\n`).digest('hex'),
747
925
  sourceCommit,
748
926
  ...(sourceRepositoryId ? { sourceRepositoryId } : {}),
@@ -753,6 +931,161 @@ export function stageRuntimeRelease(input: {
753
931
  }
754
932
  }
755
933
 
934
+
935
+ interface RuntimeReleaseTreeInspection {
936
+ sha256: string;
937
+ bytes: number;
938
+ files: number;
939
+ }
940
+
941
+ function inspectRuntimeReleaseTree(releaseRootInput: string): RuntimeReleaseTreeInspection {
942
+ const requestedRoot = resolve(releaseRootInput);
943
+ if (!existsSync(requestedRoot)) throw new Error('RUNTIME_RELEASE_TREE_MISSING');
944
+ const rootStat = lstatSync(requestedRoot);
945
+ if (!rootStat.isDirectory() || rootStat.isSymbolicLink()) throw new Error('RUNTIME_RELEASE_TREE_ROOT_INVALID');
946
+ const root = realpathSync(requestedRoot);
947
+ const records: Array<{ path: string; mode: number; bytes: number; sha256: string }> = [];
948
+ const visit = (directory: string): void => {
949
+ for (const entry of readdirSync(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
950
+ const path = join(directory, entry.name);
951
+ const stat = lstatSync(path);
952
+ if (stat.isSymbolicLink()) throw new Error(`RUNTIME_RELEASE_TREE_SYMLINK_FORBIDDEN: ${relative(root, path)}`);
953
+ if (stat.isDirectory()) {
954
+ visit(path);
955
+ continue;
956
+ }
957
+ if (!stat.isFile()) throw new Error(`RUNTIME_RELEASE_TREE_SPECIAL_FILE_FORBIDDEN: ${relative(root, path)}`);
958
+ const bytes = readFileSync(path);
959
+ records.push({
960
+ path: relative(root, path).replaceAll('\\', '/'),
961
+ mode: stat.mode & 0o777,
962
+ bytes: bytes.length,
963
+ sha256: createHash('sha256').update(bytes).digest('hex'),
964
+ });
965
+ }
966
+ };
967
+ visit(root);
968
+ const digest = createHash('sha256').update(JSON.stringify(records)).digest('hex');
969
+ return {
970
+ sha256: digest,
971
+ bytes: records.reduce((sum, record) => sum + record.bytes, 0),
972
+ files: records.length,
973
+ };
974
+ }
975
+
976
+ function preserveRuntimeReleaseTreeModes(sourceRootInput: string, targetRootInput: string): void {
977
+ const sourceRoot = resolve(sourceRootInput);
978
+ const targetRoot = resolve(targetRootInput);
979
+ const visit = (sourceDirectory: string, targetDirectory: string): void => {
980
+ for (const entry of readdirSync(sourceDirectory, { withFileTypes: true })) {
981
+ const sourcePath = join(sourceDirectory, entry.name);
982
+ const targetPath = join(targetDirectory, entry.name);
983
+ const sourceStat = lstatSync(sourcePath);
984
+ if (sourceStat.isDirectory()) {
985
+ chmodSync(targetPath, sourceStat.mode & 0o777);
986
+ visit(sourcePath, targetPath);
987
+ } else if (sourceStat.isFile()) {
988
+ // fs.cpSync applies the process umask to copied files. The release
989
+ // tree digest includes permission bits, so restore the source mode
990
+ // before comparing the staged tree with its immutable source.
991
+ chmodSync(targetPath, sourceStat.mode & 0o777);
992
+ }
993
+ }
994
+ };
995
+ chmodSync(targetRoot, lstatSync(sourceRoot).mode & 0o777);
996
+ visit(sourceRoot, targetRoot);
997
+ }
998
+
999
+ export function runtimeReleaseTreeSha256(releaseRoot: string): string {
1000
+ return inspectRuntimeReleaseTree(releaseRoot).sha256;
1001
+ }
1002
+
1003
+ export interface PromotedPortableRuntimeRelease {
1004
+ releaseId: string;
1005
+ artifactIdentity: string;
1006
+ manifestPath: string;
1007
+ manifestSha256: string;
1008
+ treeSha256: string;
1009
+ sourceReleaseRoot: string;
1010
+ targetReleaseRoot: string;
1011
+ reusedExisting: boolean;
1012
+ }
1013
+
1014
+ export function promotePortableRuntimeRelease(input: {
1015
+ sourceManifestPath: string;
1016
+ targetControllerHome: string;
1017
+ expectedTreeSha256: string;
1018
+ }): PromotedPortableRuntimeRelease {
1019
+ const sourceManifestPath = resolve(input.sourceManifestPath);
1020
+ const sourceReleaseRoot = dirname(sourceManifestPath);
1021
+ const targetControllerHome = resolve(input.targetControllerHome);
1022
+ const manifest = loadRuntimeReleaseManifest(sourceManifestPath, targetControllerHome);
1023
+ if (manifest.deploymentScope !== 'portable') throw new Error('RUNTIME_RELEASE_PROMOTION_REQUIRES_PORTABLE_ARTIFACT');
1024
+ requireCompleteCompiledRuntimeReleaseManifest(manifest);
1025
+ assertRuntimeReleaseExecutionSurface(sourceManifestPath, targetControllerHome);
1026
+
1027
+ const sourceTree = inspectRuntimeReleaseTree(sourceReleaseRoot);
1028
+ if (sourceTree.sha256 !== input.expectedTreeSha256) throw new Error('RUNTIME_RELEASE_PROMOTION_SOURCE_TREE_MISMATCH');
1029
+ const sourceManifestSha256 = createHash('sha256').update(readFileSync(sourceManifestPath)).digest('hex');
1030
+
1031
+ const releasesRoot = join(targetControllerHome, 'runtime', 'releases');
1032
+ mkdirSync(releasesRoot, { recursive: true, mode: 0o700 });
1033
+ const targetReleaseRoot = join(releasesRoot, manifest.releaseId);
1034
+ const targetManifestPath = join(targetReleaseRoot, 'manifest.json');
1035
+
1036
+ const verifyTarget = (reusedExisting: boolean): PromotedPortableRuntimeRelease => {
1037
+ const targetManifest = loadRuntimeReleaseManifest(targetManifestPath, targetControllerHome);
1038
+ if (
1039
+ targetManifest.deploymentScope !== 'portable'
1040
+ || targetManifest.releaseId !== manifest.releaseId
1041
+ || targetManifest.artifactIdentity !== manifest.artifactIdentity
1042
+ ) throw new Error('RUNTIME_RELEASE_PROMOTION_TARGET_IDENTITY_MISMATCH');
1043
+ requireCompleteCompiledRuntimeReleaseManifest(targetManifest);
1044
+ assertRuntimeReleaseExecutionSurface(targetManifestPath, targetControllerHome);
1045
+ const targetManifestSha256 = createHash('sha256').update(readFileSync(targetManifestPath)).digest('hex');
1046
+ const targetTreeSha256 = runtimeReleaseTreeSha256(targetReleaseRoot);
1047
+ if (targetManifestSha256 !== sourceManifestSha256 || targetTreeSha256 !== sourceTree.sha256) {
1048
+ throw new Error('RUNTIME_RELEASE_PROMOTION_NOT_BYTE_IDENTICAL');
1049
+ }
1050
+ return {
1051
+ releaseId: manifest.releaseId,
1052
+ artifactIdentity: manifest.artifactIdentity,
1053
+ manifestPath: targetManifestPath,
1054
+ manifestSha256: targetManifestSha256,
1055
+ treeSha256: targetTreeSha256,
1056
+ sourceReleaseRoot,
1057
+ targetReleaseRoot,
1058
+ reusedExisting,
1059
+ };
1060
+ };
1061
+
1062
+ if (existsSync(targetReleaseRoot)) return verifyTarget(true);
1063
+
1064
+ assertStorageHeadroom(releasesRoot, {
1065
+ operation: 'runtime_release_promotion',
1066
+ requiredBytes: sourceTree.bytes,
1067
+ reserveBytes: 64 * 1024 * 1024,
1068
+ });
1069
+ const staging = join(releasesRoot, `.${manifest.releaseId}.promote-${process.pid}-${randomUUID().slice(0, 8)}`);
1070
+ try {
1071
+ cpSync(sourceReleaseRoot, staging, {
1072
+ recursive: true,
1073
+ force: false,
1074
+ errorOnExist: true,
1075
+ preserveTimestamps: false,
1076
+ dereference: false,
1077
+ });
1078
+ preserveRuntimeReleaseTreeModes(sourceReleaseRoot, staging);
1079
+ const stagedTree = inspectRuntimeReleaseTree(staging);
1080
+ if (stagedTree.sha256 !== sourceTree.sha256) throw new Error('RUNTIME_RELEASE_PROMOTION_STAGING_TREE_MISMATCH');
1081
+ renameSync(staging, targetReleaseRoot);
1082
+ return verifyTarget(false);
1083
+ } catch (error) {
1084
+ rmSync(staging, { recursive: true, force: true });
1085
+ throw error;
1086
+ }
1087
+ }
1088
+
756
1089
  export function assertRuntimeReleaseFiles(release: StagedRuntimeRelease, dependencies: { platform?: NodeJS.Platform; inspectMacOSRuntime?: (executable: string) => MacOSRuntimeCodeSigning } = {}): void {
757
1090
  const assertRegularFile = (path: string, missingCode: string): void => {
758
1091
  if (!existsSync(path)) throw new Error(`${missingCode}: ${path}`);
@@ -803,6 +1136,13 @@ export function assertRuntimeReleaseFiles(release: StagedRuntimeRelease, depende
803
1136
  assertFileIdentity(runtimePath, release.artifactIdentity);
804
1137
  assertComponentFile({ path: join(release.releasePath, 'forge-runtime-bundle.js'), identity: release.runtimeBundleArtifactIdentity, missingCode: 'RUNTIME_RELEASE_BUNDLE_MISSING' });
805
1138
  const platform = dependencies.platform ?? process.platform;
1139
+ const runtimeInterpreterEntrypoint = platform === 'win32' ? 'forge-runtime-bun.exe' : 'forge-runtime-bun';
1140
+ assertComponentFile({
1141
+ path: join(release.releasePath, runtimeInterpreterEntrypoint),
1142
+ identity: release.runtimeInterpreterArtifactIdentity,
1143
+ missingCode: 'RUNTIME_RELEASE_INTERPRETER_MISSING',
1144
+ executable: true,
1145
+ });
806
1146
  if (platform === 'darwin' && release.macosCodeSigning) {
807
1147
  const actual = (dependencies.inspectMacOSRuntime ?? inspectMacOSRuntimeCodeSigning)(runtimePath);
808
1148
  if (actual.identifier !== release.macosCodeSigning.identifier
@@ -813,10 +1153,14 @@ export function assertRuntimeReleaseFiles(release: StagedRuntimeRelease, depende
813
1153
  }
814
1154
  }
815
1155
  assertComponentFile({ path: join(release.releasePath, 'forge-cli'), identity: release.diagnosticArtifactIdentity, missingCode: 'RUNTIME_RELEASE_DIAGNOSTIC_ENTRYPOINT_MISSING', executable: true });
1156
+ assertComponentFile({ path: join(release.releasePath, 'forge-mcp-gateway'), identity: release.connectorArtifactIdentity, missingCode: 'RUNTIME_RELEASE_CONNECTOR_ENTRYPOINT_MISSING', executable: true });
816
1157
  assertComponentFile({ path: join(release.releasePath, 'browser-node-bridge-host.js'), identity: release.browserNodeBridgeArtifactIdentity, missingCode: 'RUNTIME_RELEASE_BROWSER_NODE_HOST_MISSING', executable: true });
817
1158
  assertComponentFile({ path: join(release.releasePath, 'browser-handoff-host.js'), identity: release.browserHandoffArtifactIdentity, missingCode: 'RUNTIME_RELEASE_BROWSER_HANDOFF_HOST_MISSING', executable: true });
1159
+ assertComponentFile({ path: join(release.releasePath, 'forge-workflow-supervisor-native-host'), identity: release.workflowSupervisorNativeHostArtifactIdentity, missingCode: 'RUNTIME_RELEASE_WORKFLOW_SUPERVISOR_NATIVE_HOST_MISSING', executable: true });
818
1160
  assertComponentFile({ path: join(release.releasePath, 'process-runner.js'), identity: release.processRunnerArtifactIdentity, missingCode: 'RUNTIME_RELEASE_PROCESS_RUNNER_MISSING', executable: true });
819
1161
  assertComponentFile({ path: join(release.releasePath, 'forge-check-runner'), identity: release.checkRunnerArtifactIdentity, missingCode: 'RUNTIME_RELEASE_CHECK_RUNNER_MISSING', executable: true });
1162
+ assertComponentFile({ path: join(release.releasePath, 'forge-typescript-navigation'), identity: release.typescriptNavigationArtifactIdentity, missingCode: 'RUNTIME_RELEASE_TYPESCRIPT_NAVIGATION_MISSING', executable: true });
1163
+ assertComponentFile({ path: join(release.releasePath, 'forge-context-pack'), identity: release.contextPackArtifactIdentity, missingCode: 'RUNTIME_RELEASE_CONTEXT_PACK_MISSING', executable: true });
820
1164
  assertComponentFile({ path: join(release.releasePath, 'forge-scheduler-worker'), identity: release.schedulerWorkerArtifactIdentity, missingCode: 'RUNTIME_RELEASE_SCHEDULER_WORKER_MISSING', executable: true });
821
1165
  assertComponentFile({ path: join(release.releasePath, 'forge-periodic-cleanup'), identity: release.periodicCleanupArtifactIdentity, missingCode: 'RUNTIME_RELEASE_PERIODIC_CLEANUP_MISSING', executable: true });
822
1166
  assertComponentFile({ path: join(release.releasePath, 'forge-plugin-action-sidecar'), identity: release.pluginActionSidecarArtifactIdentity, missingCode: 'RUNTIME_RELEASE_PLUGIN_ACTION_SIDECAR_MISSING', executable: true });