@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
@@ -0,0 +1,191 @@
1
+ import { randomBytes } from 'crypto';
2
+ import { existsSync, mkdirSync, rmSync, statSync, writeFileSync } from 'fs';
3
+ import { chmodSync } from 'fs';
4
+ import { basename, dirname, join, resolve } from 'path';
5
+ import { backupControlPlaneDatabase, type ControlPlaneDatabaseInspection } from '../control-plane/persistence/sqlite-store';
6
+ import { normalizeRuntimeDeploymentTopology } from './deployment-topology';
7
+ import { forgeRuntimeServicePaths, readForgeRuntimeServiceConfig, writeForgeRuntimeServiceConfig, type ForgeRuntimeServiceConfig } from './service';
8
+
9
+ export interface StableExecutionLane {
10
+ schemaVersion: 1;
11
+ kind: 'stable';
12
+ controllerHome: string;
13
+ serviceLabel: string;
14
+ port: number;
15
+ authTokenFile: string;
16
+ }
17
+
18
+ export interface CandidateExecutionLane {
19
+ schemaVersion: 1;
20
+ kind: 'candidate';
21
+ sessionId: string;
22
+ controllerHome: string;
23
+ serviceLabel: string;
24
+ port: number;
25
+ authTokenFile: string;
26
+ databaseSnapshotPath: string;
27
+ sourceStableControllerHome: string;
28
+ createdAt: string;
29
+ }
30
+
31
+ function requireSessionId(value: string): string {
32
+ const sessionId = value.trim();
33
+ if (!/^[A-Za-z0-9][A-Za-z0-9_-]{7,119}$/.test(sessionId)) {
34
+ throw new Error('RUNTIME_CANDIDATE_SESSION_ID_INVALID');
35
+ }
36
+ return sessionId;
37
+ }
38
+
39
+ function requireCandidatePort(port: number, stablePort: number): number {
40
+ if (!Number.isInteger(port) || port < 1 || port > 65_535) throw new Error('RUNTIME_CANDIDATE_PORT_INVALID');
41
+ if (port === stablePort) throw new Error('RUNTIME_CANDIDATE_PORT_COLLIDES_WITH_STABLE');
42
+ return port;
43
+ }
44
+
45
+ function candidateTokenPath(controllerHome: string): string {
46
+ return join(controllerHome, 'mcp', 'runtime-token');
47
+ }
48
+
49
+ export function readStableExecutionLane(controllerHome: string): StableExecutionLane {
50
+ const home = resolve(controllerHome);
51
+ const paths = forgeRuntimeServicePaths(home);
52
+ const config = readForgeRuntimeServiceConfig(paths.configPath, { missingRepositoryRoot: 'omit' });
53
+ return {
54
+ schemaVersion: 1,
55
+ kind: 'stable',
56
+ controllerHome: home,
57
+ serviceLabel: paths.label,
58
+ port: config.port,
59
+ authTokenFile: config.authTokenFile,
60
+ };
61
+ }
62
+
63
+ /** Pure lane derivation. It never starts a service or writes either Home. */
64
+ export function planCandidateExecutionLane(input: {
65
+ stable: StableExecutionLane;
66
+ candidateControllerHome: string;
67
+ candidatePort: number;
68
+ sessionId: string;
69
+ }): CandidateExecutionLane {
70
+ const candidateHome = resolve(input.candidateControllerHome);
71
+ if (candidateHome === resolve(input.stable.controllerHome)) {
72
+ throw new Error('RUNTIME_CANDIDATE_CONTROLLER_HOME_COLLIDES_WITH_STABLE');
73
+ }
74
+ const port = requireCandidatePort(input.candidatePort, input.stable.port);
75
+ const paths = forgeRuntimeServicePaths(candidateHome);
76
+ if (paths.label === input.stable.serviceLabel) throw new Error('RUNTIME_CANDIDATE_SERVICE_LABEL_COLLIDES_WITH_STABLE');
77
+ return {
78
+ schemaVersion: 1,
79
+ kind: 'candidate',
80
+ sessionId: requireSessionId(input.sessionId),
81
+ controllerHome: candidateHome,
82
+ serviceLabel: paths.label,
83
+ port,
84
+ authTokenFile: candidateTokenPath(candidateHome),
85
+ databaseSnapshotPath: join(candidateHome, 'control-plane.sqlite'),
86
+ sourceStableControllerHome: resolve(input.stable.controllerHome),
87
+ createdAt: new Date().toISOString(),
88
+ };
89
+ }
90
+
91
+ function createPrivateCandidateToken(stableTokenPath: string, destination: string): void {
92
+ if (!existsSync(stableTokenPath) || !statSync(stableTokenPath).isFile()) {
93
+ throw new Error('RUNTIME_CANDIDATE_STABLE_AUTH_TOKEN_MISSING');
94
+ }
95
+ mkdirSync(dirname(destination), { recursive: true, mode: 0o700 });
96
+ writeFileSync(destination, `${randomBytes(32).toString('base64url')}\n`, { encoding: 'utf8', mode: 0o600, flag: 'wx' });
97
+ try { chmodSync(destination, 0o600); } catch { /* platform best effort */ }
98
+ }
99
+
100
+ function candidateServiceConfig(stable: ForgeRuntimeServiceConfig, lane: CandidateExecutionLane): ForgeRuntimeServiceConfig {
101
+ const topology = normalizeRuntimeDeploymentTopology(stable.topology);
102
+ return {
103
+ ...stable,
104
+ controllerHome: lane.controllerHome,
105
+ port: lane.port,
106
+ authTokenFile: lane.authTokenFile,
107
+ // Candidate B may verify the Supervisor socket and internal lifecycle,
108
+ // but it must never submit external browser effects against Stable A's
109
+ // real conversation during an isolated canary.
110
+ topology: {
111
+ ...topology,
112
+ components: { ...topology.components },
113
+ },
114
+ };
115
+ }
116
+
117
+ /**
118
+ * Create the only permitted Candidate B mutable foundation: a fresh Controller
119
+ * Home with a consistent SQLite snapshot and an independent declarative
120
+ * service contract. It deliberately does not copy Stable A's Runtime release
121
+ * authority and never starts/stops a service; portable artifacts are published into B under B's own authority.
122
+ */
123
+ export function createCandidateExecutionLane(input: {
124
+ stableControllerHome: string;
125
+ candidateControllerHome: string;
126
+ candidatePort: number;
127
+ sessionId: string;
128
+ }): { stable: StableExecutionLane; candidate: CandidateExecutionLane; database: ControlPlaneDatabaseInspection } {
129
+ const stable = readStableExecutionLane(input.stableControllerHome);
130
+ const candidate = planCandidateExecutionLane({
131
+ stable,
132
+ candidateControllerHome: input.candidateControllerHome,
133
+ candidatePort: input.candidatePort,
134
+ sessionId: input.sessionId,
135
+ });
136
+ if (existsSync(candidate.controllerHome)) throw new Error('RUNTIME_CANDIDATE_CONTROLLER_HOME_ALREADY_EXISTS');
137
+ try {
138
+ createPrivateCandidateToken(stable.authTokenFile, candidate.authTokenFile);
139
+ const database = backupControlPlaneDatabase(stable.controllerHome, candidate.databaseSnapshotPath);
140
+ writeForgeRuntimeServiceConfig(candidateServiceConfig(
141
+ readForgeRuntimeServiceConfig(forgeRuntimeServicePaths(stable.controllerHome).configPath, { missingRepositoryRoot: 'omit' }),
142
+ candidate,
143
+ ));
144
+ assertCandidateExecutionLaneIsolation(stable, candidate);
145
+ return { stable, candidate, database };
146
+ } catch (error) {
147
+ // No recursive cleanup is attempted here: this function never guesses at
148
+ // a pre-existing user directory. The only writable target was required to
149
+ // be absent, so the caller can inspect or explicitly retire a partial B.
150
+ throw error;
151
+ }
152
+ }
153
+
154
+ export function assertCandidateExecutionLaneIsolation(
155
+ stable: StableExecutionLane,
156
+ candidate: CandidateExecutionLane,
157
+ ): void {
158
+ if (resolve(stable.controllerHome) === resolve(candidate.controllerHome)) {
159
+ throw new Error('RUNTIME_CANDIDATE_CONTROLLER_HOME_COLLIDES_WITH_STABLE');
160
+ }
161
+ if (stable.port === candidate.port) throw new Error('RUNTIME_CANDIDATE_PORT_COLLIDES_WITH_STABLE');
162
+ if (stable.serviceLabel === candidate.serviceLabel) throw new Error('RUNTIME_CANDIDATE_SERVICE_LABEL_COLLIDES_WITH_STABLE');
163
+ if (resolve(stable.authTokenFile) === resolve(candidate.authTokenFile)) {
164
+ throw new Error('RUNTIME_CANDIDATE_AUTH_TOKEN_COLLIDES_WITH_STABLE');
165
+ }
166
+ if (resolve(candidate.databaseSnapshotPath) !== resolve(candidate.controllerHome, 'control-plane.sqlite')) {
167
+ throw new Error('RUNTIME_CANDIDATE_DATABASE_PATH_INVALID');
168
+ }
169
+ }
170
+
171
+ /**
172
+ * Remove one retired Candidate B home after its ReleaseSession has reached a
173
+ * terminal state. The path fence is deliberately derived from Stable A and
174
+ * the session identity so terminal cleanup can never target an arbitrary
175
+ * Controller Home.
176
+ */
177
+ export function removeRetiredCandidateExecutionLane(
178
+ stable: StableExecutionLane,
179
+ candidate: Pick<CandidateExecutionLane, 'controllerHome' | 'sessionId'>,
180
+ ): boolean {
181
+ const stableHome = resolve(stable.controllerHome);
182
+ const candidateHome = resolve(candidate.controllerHome);
183
+ const candidateRoot = resolve(dirname(stableHome), 'candidate-runtime-lanes');
184
+ if (candidateHome === stableHome) throw new Error('RUNTIME_CANDIDATE_CLEANUP_STABLE_COLLISION');
185
+ if (resolve(dirname(candidateHome)) !== candidateRoot || basename(candidateHome) !== candidate.sessionId) {
186
+ throw new Error('RUNTIME_CANDIDATE_CLEANUP_PATH_INVALID');
187
+ }
188
+ if (!existsSync(candidateHome)) return false;
189
+ rmSync(candidateHome, { recursive: true, force: true });
190
+ return true;
191
+ }
@@ -1,5 +1,5 @@
1
1
  import { randomUUID } from 'crypto';
2
- import { mkdirSync, statSync } from 'fs';
2
+ import { statSync } from 'fs';
3
3
  import { writeJsonAtomic } from '../shared/json-files';
4
4
  import { ensureForgeInstanceIdentity } from '../../../packages/kernel/identity/api/index';
5
5
  import { dirname, join } from 'path';
@@ -10,7 +10,6 @@ import {
10
10
  enableControlPlaneReadConnectionReuse,
11
11
  inspectControlPlaneDatabase,
12
12
  } from '../control-plane/persistence/sqlite-store';
13
- import { activateExclusiveWorkAdmission } from '../control-plane/facade/work-admission-policy';
14
13
  import { closeCodeGraphReadProviderSessions } from '../context/codegraph-read-provider';
15
14
  import { cancelAllLightweightProcesses } from '../execution/process-runtime/lightweight-managed';
16
15
  import {
@@ -24,11 +23,14 @@ import { acquireRuntimeOwnership, type RuntimeOwnershipHandle } from './ownershi
24
23
  import { RuntimeReadinessState } from './readiness';
25
24
  import { loadRuntimeReleaseManifest, requireCompleteCompiledRuntimeReleaseManifest } from './release-manifest';
26
25
  import { ensureActiveRuntimeRelease, readRuntimeReleaseAuthority, type RuntimeReleaseAuthority } from './release-store';
26
+ import { migrateReleaseDurableState } from '../release/release-state-migration';
27
27
  import { bindRuntimeWriteClaim, clearRuntimeWriteClaim } from './write-fence';
28
28
  import { startInProcessScheduler, type RuntimeSchedulerHandle } from './scheduler';
29
29
  import { startConfiguredRuntimeLocalBridge, type RuntimeLocalBridgeHandle } from './local-bridge';
30
30
  import { startActiveExecutionPowerAssertion, type RuntimePowerAssertionHandle } from './active-execution-power-assertion';
31
- import { removeRuntimeStatusSnapshot, writeRuntimeStatusSnapshot } from './status';
31
+ import { startWorkflowSupervisorRuntime, type RuntimeWorkflowSupervisorHandle } from './workflow-supervisor-runtime';
32
+ import { normalizeRuntimeDeploymentTopology, type RuntimeDeploymentTopology } from './deployment-topology';
33
+ import { removeRuntimeStartupFailureEvidence, removeRuntimeStatusSnapshot, writeRuntimeStartupFailureEvidence, writeRuntimeStatusSnapshot } from './status';
32
34
  import type {
33
35
  CanonicalRuntimeConfig,
34
36
  CanonicalRuntimeStatusSnapshot,
@@ -43,6 +45,7 @@ export interface RuntimeReleaseAuthorityMonitor {
43
45
 
44
46
  export interface CanonicalRuntimeDependencies {
45
47
  loadReleaseManifest(path: string, controllerHome: string): RuntimeReleaseManifest;
48
+ migrateReleaseState(controllerHome: string): void;
46
49
  ensureReleaseAuthority(controllerHome: string, manifestPath: string): RuntimeReleaseAuthority;
47
50
  readReleaseAuthority(controllerHome: string): RuntimeReleaseAuthority | undefined;
48
51
  startReleaseAuthorityMonitor(observe: () => void): RuntimeReleaseAuthorityMonitor;
@@ -52,6 +55,7 @@ export interface CanonicalRuntimeDependencies {
52
55
  startScheduler(input: Parameters<typeof startInProcessScheduler>[0]): RuntimeSchedulerHandle;
53
56
  startLocalBridge(input: { controllerHome: string; repositoryRoot?: string }): Promise<RuntimeLocalBridgeHandle | undefined>;
54
57
  startPowerAssertion(input: { controllerHome: string; runtimePid: number }): RuntimePowerAssertionHandle;
58
+ startWorkflowSupervisor(controllerHome: string, options?: { nativeBrowserAdapter?: boolean }): Promise<RuntimeWorkflowSupervisorHandle>;
55
59
  startTransport(options: Parameters<typeof startRuntimeMcpTransport>[0]): Promise<RuntimeMcpTransportHandle>;
56
60
  runMcpProbe(endpoint: string, authToken: string): Promise<void>;
57
61
  collectRuntimeSourceIdentity: typeof collectRuntimeSourceIdentity;
@@ -60,7 +64,20 @@ export interface CanonicalRuntimeDependencies {
60
64
  stopContextReadHelpers(): Promise<void>;
61
65
  computeToolSurfaceFingerprint: typeof runtimeGatewayToolSurfaceFingerprint;
62
66
  ensureForgeInstanceIdentity: typeof ensureForgeInstanceIdentity;
63
- startJscSamplingProfiler(directory: string): Promise<void>;
67
+ captureJscSamplingProfile(options: { durationMs: number; sampleIntervalUs: number }): Promise<{
68
+ requestedDurationMs: number;
69
+ elapsedMs: number;
70
+ sampleIntervalUs: number;
71
+ functions: string;
72
+ bytecodes: string;
73
+ stackTraces: {
74
+ interval: number | null;
75
+ totalTraceCount: number;
76
+ retainedTraceCount: number;
77
+ traces: Array<{ timestamp: number | null; frames: Array<Record<string, unknown>> }>;
78
+ sources: Array<Record<string, unknown>>;
79
+ };
80
+ }>;
64
81
  }
65
82
 
66
83
  async function defaultMcpProbe(endpoint: string, authToken: string): Promise<void> {
@@ -87,6 +104,12 @@ async function defaultMcpProbe(endpoint: string, authToken: string): Promise<voi
87
104
  }
88
105
 
89
106
  const DEFAULT_RELEASE_AUTHORITY_MONITOR_INTERVAL_MS = 1_000;
107
+ const JSC_SAMPLING_DURATION_MS = 2_000;
108
+ const JSC_SAMPLING_INTERVAL_US = 1_000;
109
+ const JSC_SAMPLING_TRACE_LIMIT = 2_000;
110
+ const JSC_SAMPLING_FRAME_LIMIT = 32;
111
+ const JSC_SAMPLING_SOURCE_LIMIT = 512;
112
+ const JSC_SAMPLING_REPORT_CHAR_LIMIT = 128 * 1024;
90
113
 
91
114
  function startDefaultReleaseAuthorityMonitor(observe: () => void): RuntimeReleaseAuthorityMonitor {
92
115
  const timer = setInterval(observe, DEFAULT_RELEASE_AUTHORITY_MONITOR_INTERVAL_MS);
@@ -94,14 +117,70 @@ function startDefaultReleaseAuthorityMonitor(observe: () => void): RuntimeReleas
94
117
  return { stop: () => clearInterval(timer) };
95
118
  }
96
119
 
97
- async function startDefaultJscSamplingProfiler(directory: string): Promise<void> {
98
- mkdirSync(directory, { recursive: true });
99
- const { startSamplingProfiler } = await import('bun:jsc');
100
- startSamplingProfiler(directory);
120
+ async function captureDefaultJscSamplingProfile(options: { durationMs: number; sampleIntervalUs: number }): Promise<{
121
+ requestedDurationMs: number;
122
+ elapsedMs: number;
123
+ sampleIntervalUs: number;
124
+ functions: string;
125
+ bytecodes: string;
126
+ stackTraces: {
127
+ interval: number | null;
128
+ totalTraceCount: number;
129
+ retainedTraceCount: number;
130
+ traces: Array<{ timestamp: number | null; frames: Array<Record<string, unknown>> }>;
131
+ sources: Array<Record<string, unknown>>;
132
+ };
133
+ }> {
134
+ const { profile } = await import('bun:jsc');
135
+ const startedAt = performance.now();
136
+ const sampling = await profile(
137
+ () => new Promise<void>((resolve) => setTimeout(resolve, options.durationMs)),
138
+ options.sampleIntervalUs,
139
+ );
140
+ // Bun's current runtime returns an object here even though bun-types still
141
+ // declares SamplingProfile.stackTraces as string[]. Treat the runtime value
142
+ // as diagnostic input and normalize it defensively instead of trusting that
143
+ // stale declaration at the production boundary.
144
+ const rawStackTraces = sampling.stackTraces as unknown as {
145
+ interval?: unknown;
146
+ traces?: unknown;
147
+ sources?: unknown;
148
+ };
149
+ const rawTraces = Array.isArray(rawStackTraces?.traces) ? rawStackTraces.traces : [];
150
+ const traces = rawTraces.slice(-JSC_SAMPLING_TRACE_LIMIT).map((trace) => {
151
+ const record = trace && typeof trace === 'object' && !Array.isArray(trace)
152
+ ? trace as Record<string, unknown>
153
+ : {};
154
+ const frames = Array.isArray(record.frames)
155
+ ? record.frames.filter((frame): frame is Record<string, unknown> => Boolean(frame) && typeof frame === 'object' && !Array.isArray(frame)).slice(0, JSC_SAMPLING_FRAME_LIMIT)
156
+ : [];
157
+ return {
158
+ timestamp: typeof record.timestamp === 'number' ? record.timestamp : null,
159
+ frames,
160
+ };
161
+ });
162
+ const sources = Array.isArray(rawStackTraces?.sources)
163
+ ? rawStackTraces.sources.filter((source): source is Record<string, unknown> => Boolean(source) && typeof source === 'object' && !Array.isArray(source)).slice(0, JSC_SAMPLING_SOURCE_LIMIT)
164
+ : [];
165
+ return {
166
+ requestedDurationMs: options.durationMs,
167
+ elapsedMs: Math.max(0, performance.now() - startedAt),
168
+ sampleIntervalUs: options.sampleIntervalUs,
169
+ functions: sampling.functions.slice(0, JSC_SAMPLING_REPORT_CHAR_LIMIT),
170
+ bytecodes: sampling.bytecodes.slice(0, JSC_SAMPLING_REPORT_CHAR_LIMIT),
171
+ stackTraces: {
172
+ interval: typeof rawStackTraces?.interval === 'number' ? rawStackTraces.interval : null,
173
+ totalTraceCount: rawTraces.length,
174
+ retainedTraceCount: traces.length,
175
+ traces,
176
+ sources,
177
+ },
178
+ };
101
179
  }
102
180
 
103
181
  const DEFAULT_DEPENDENCIES: CanonicalRuntimeDependencies = {
104
182
  loadReleaseManifest: loadRuntimeReleaseManifest,
183
+ migrateReleaseState: migrateReleaseDurableState,
105
184
  ensureReleaseAuthority: ensureActiveRuntimeRelease,
106
185
  readReleaseAuthority: readRuntimeReleaseAuthority,
107
186
  startReleaseAuthorityMonitor: startDefaultReleaseAuthorityMonitor,
@@ -111,6 +190,7 @@ const DEFAULT_DEPENDENCIES: CanonicalRuntimeDependencies = {
111
190
  startScheduler: startInProcessScheduler,
112
191
  startLocalBridge: startConfiguredRuntimeLocalBridge,
113
192
  startPowerAssertion: startActiveExecutionPowerAssertion,
193
+ startWorkflowSupervisor: startWorkflowSupervisorRuntime,
114
194
  startTransport: startRuntimeMcpTransport,
115
195
  runMcpProbe: defaultMcpProbe,
116
196
  collectRuntimeSourceIdentity,
@@ -119,18 +199,20 @@ const DEFAULT_DEPENDENCIES: CanonicalRuntimeDependencies = {
119
199
  stopContextReadHelpers: closeCodeGraphReadProviderSessions,
120
200
  computeToolSurfaceFingerprint: runtimeGatewayToolSurfaceFingerprint,
121
201
  ensureForgeInstanceIdentity,
122
- startJscSamplingProfiler: startDefaultJscSamplingProfiler,
202
+ captureJscSamplingProfile: captureDefaultJscSamplingProfile,
123
203
  };
124
204
 
125
205
  export class CanonicalForgeRuntime {
126
206
  readonly forgeInstanceId: string;
127
207
  readonly runtimeInstanceId: string;
208
+ readonly topology: RuntimeDeploymentTopology;
128
209
  private readonly readinessState = new RuntimeReadinessState();
129
210
  private readonly dependencies: CanonicalRuntimeDependencies;
130
211
  private ownership?: RuntimeOwnershipHandle;
131
212
  private scheduler?: RuntimeSchedulerHandle;
132
213
  private localBridge?: RuntimeLocalBridgeHandle;
133
214
  private powerAssertion?: RuntimePowerAssertionHandle;
215
+ private workflowSupervisor?: RuntimeWorkflowSupervisorHandle;
134
216
  private toolSurfaceFingerprint?: string;
135
217
  private transport?: RuntimeMcpTransportHandle;
136
218
  private controller?: RuntimeControllerServices;
@@ -144,8 +226,7 @@ export class CanonicalForgeRuntime {
144
226
  private jscHeapDiagnosticsSignalHandler?: () => void;
145
227
  private jscHeapDiagnosticsCaptureInFlight = false;
146
228
  private jscSamplingProfilerSignalHandler?: () => void;
147
- private jscSamplingProfilerStartInFlight = false;
148
- private jscSamplingProfilerStarted = false;
229
+ private jscSamplingProfileCaptureInFlight = false;
149
230
  lastExit?: RuntimeExitEvidence;
150
231
 
151
232
  constructor(
@@ -153,6 +234,7 @@ export class CanonicalForgeRuntime {
153
234
  dependencies: Partial<CanonicalRuntimeDependencies> = {},
154
235
  ) {
155
236
  this.runtimeInstanceId = config.runtimeInstanceId?.trim() || `runtime_${randomUUID().replaceAll('-', '')}`;
237
+ this.topology = normalizeRuntimeDeploymentTopology(config.topology);
156
238
  this.dependencies = { ...DEFAULT_DEPENDENCIES, ...dependencies };
157
239
  if (!config.controllerHome.trim()) throw new Error('RUNTIME_CONFIG_REQUIRED: controllerHome');
158
240
  if (config.repositoryRoot?.trim()) {
@@ -183,7 +265,10 @@ export class CanonicalForgeRuntime {
183
265
  const handler = () => {
184
266
  if (this.jscHeapDiagnosticsCaptureInFlight) return;
185
267
  this.jscHeapDiagnosticsCaptureInFlight = true;
186
- void import('bun:jsc').then(({ heapStats, memoryUsage }) => {
268
+ void import('bun:jsc').then(({ fullGC, heapStats, memoryUsage }) => {
269
+ const gcStartedAt = performance.now();
270
+ const fullGcResult = fullGC();
271
+ const fullGcDurationMs = Math.max(0, performance.now() - gcStartedAt);
187
272
  const heap = heapStats();
188
273
  const topTypes = (counts: Record<string, number>, limit: number) => Object.entries(counts)
189
274
  .sort((left, right) => right[1] - left[1])
@@ -195,6 +280,12 @@ export class CanonicalForgeRuntime {
195
280
  pid: process.pid,
196
281
  runtimeInstanceId: this.runtimeInstanceId,
197
282
  releaseId: this.release?.releaseId,
283
+ gc: {
284
+ forced: true,
285
+ kind: 'full',
286
+ durationMs: fullGcDurationMs,
287
+ result: fullGcResult,
288
+ },
198
289
  heap: {
199
290
  heapSize: heap.heapSize,
200
291
  heapCapacity: heap.heapCapacity,
@@ -235,26 +326,41 @@ export class CanonicalForgeRuntime {
235
326
  private installJscSamplingProfilerSignal(): void {
236
327
  if (process.platform === 'win32' || this.jscSamplingProfilerSignalHandler) return;
237
328
  const handler = () => {
238
- if (this.jscSamplingProfilerStarted || this.jscSamplingProfilerStartInFlight) return;
239
- this.jscSamplingProfilerStartInFlight = true;
240
- const directory = join(this.config.controllerHome, 'diagnostics', 'jsc-profile');
241
- void this.dependencies.startJscSamplingProfiler(directory).then(() => {
242
- this.jscSamplingProfilerStarted = true;
329
+ if (this.jscSamplingProfileCaptureInFlight) return;
330
+ this.jscSamplingProfileCaptureInFlight = true;
331
+ void this.dependencies.captureJscSamplingProfile({
332
+ durationMs: JSC_SAMPLING_DURATION_MS,
333
+ sampleIntervalUs: JSC_SAMPLING_INTERVAL_US,
334
+ }).then((sampling) => {
335
+ const path = join(this.config.controllerHome, 'diagnostics', 'jsc-sampling-profile.json');
336
+ writeJsonAtomic(path, {
337
+ schemaVersion: 1,
338
+ capturedAt: new Date().toISOString(),
339
+ pid: process.pid,
340
+ runtimeInstanceId: this.runtimeInstanceId,
341
+ releaseId: this.release?.releaseId,
342
+ bounded: true,
343
+ ...sampling,
344
+ });
243
345
  process.stderr.write(`${JSON.stringify({
244
- event: 'forge_runtime_jsc_sampling_profiler_started',
346
+ event: 'forge_runtime_jsc_sampling_profile_captured',
245
347
  runtimeInstanceId: this.runtimeInstanceId,
246
- directory,
348
+ path,
349
+ requestedDurationMs: sampling.requestedDurationMs,
350
+ elapsedMs: sampling.elapsedMs,
351
+ sampleIntervalUs: sampling.sampleIntervalUs,
352
+ retainedTraceCount: sampling.stackTraces.retainedTraceCount,
247
353
  observedAt: new Date().toISOString(),
248
354
  })}\n`);
249
355
  }).catch((error) => {
250
356
  process.stderr.write(`${JSON.stringify({
251
- event: 'forge_runtime_jsc_sampling_profiler_failed',
357
+ event: 'forge_runtime_jsc_sampling_profile_failed',
252
358
  runtimeInstanceId: this.runtimeInstanceId,
253
359
  message: error instanceof Error ? error.message : String(error),
254
360
  observedAt: new Date().toISOString(),
255
361
  })}\n`);
256
362
  }).finally(() => {
257
- this.jscSamplingProfilerStartInFlight = false;
363
+ this.jscSamplingProfileCaptureInFlight = false;
258
364
  });
259
365
  };
260
366
  process.on('SIGUSR1', handler);
@@ -339,7 +445,7 @@ export class CanonicalForgeRuntime {
339
445
  if (this.started) throw new Error('RUNTIME_ALREADY_STARTED');
340
446
  this.started = true;
341
447
  this.readinessState.markNotReady();
342
- let stage: 'release' | 'ownership' | 'source' | 'database' | 'scheduler' | 'localBridge' | 'transport' | 'probe' = 'release';
448
+ let stage: 'release' | 'ownership' | 'source' | 'database' | 'supervisor' | 'scheduler' | 'localBridge' | 'transport' | 'probe' = 'release';
343
449
  try {
344
450
  this.release = this.dependencies.loadReleaseManifest(this.config.releaseManifestPath, this.config.controllerHome);
345
451
 
@@ -347,6 +453,7 @@ export class CanonicalForgeRuntime {
347
453
  this.ownership = this.dependencies.acquireOwnership(this.config.controllerHome, this.runtimeInstanceId);
348
454
 
349
455
  stage = 'release';
456
+ this.dependencies.migrateReleaseState(this.config.controllerHome);
350
457
  const releaseAuthority = this.dependencies.ensureReleaseAuthority(this.config.controllerHome, this.config.releaseManifestPath);
351
458
  stage = 'source';
352
459
  // A compiled release is a closed execution surface. Fail before Scheduler
@@ -400,11 +507,15 @@ export class CanonicalForgeRuntime {
400
507
  this.installJscSamplingProfilerSignal();
401
508
  this.readinessState.setDiagnostic('database', 'pass');
402
509
  this.publishStatus();
403
- if (this.config.exclusiveWorkId) {
404
- activateExclusiveWorkAdmission(this.config.controllerHome, {
405
- allowedWorkId: this.config.exclusiveWorkId,
406
- reason: 'P0 canonical single Runtime migration isolation',
510
+ if (this.topology.components.workflowSupervisor) {
511
+ stage = 'supervisor';
512
+ this.workflowSupervisor = await this.dependencies.startWorkflowSupervisor(this.config.controllerHome, {
513
+ nativeBrowserAdapter: this.topology.components.workflowSupervisorNativeBrowser,
407
514
  });
515
+ void this.workflowSupervisor.done.then(
516
+ () => this.failCore('WORKFLOW_SUPERVISOR_STOPPED', 'Workflow Supervisor stopped while Runtime was active.'),
517
+ (error) => this.failCore('WORKFLOW_SUPERVISOR_FAILED', error instanceof Error ? error.message : String(error)),
518
+ );
408
519
  }
409
520
 
410
521
  stage = 'scheduler';
@@ -464,12 +575,30 @@ export class CanonicalForgeRuntime {
464
575
  this.readinessState.setDiagnostic('mcpEndToEnd', 'pass');
465
576
  this.readinessState.markReady();
466
577
  this.publishStatus();
578
+ removeRuntimeStartupFailureEvidence(this.config.controllerHome);
467
579
  stage = 'release';
468
580
  this.startReleaseAuthorityMonitor();
469
581
  } catch (error) {
470
582
  const reason = this.startupReason(stage);
583
+ const message = error instanceof Error ? error.message : String(error);
471
584
  this.markStartupFailure(stage, reason);
472
- await this.stop(reason, error instanceof Error ? error.message : String(error));
585
+ try {
586
+ writeRuntimeStartupFailureEvidence(this.config.controllerHome, {
587
+ schemaVersion: 1,
588
+ runtimeInstanceId: this.runtimeInstanceId,
589
+ stage,
590
+ reasonCode: reason,
591
+ message,
592
+ ...(this.release ? {
593
+ releaseId: this.release.releaseId,
594
+ artifactIdentity: this.release.artifactIdentity,
595
+ } : {}),
596
+ observedAt: new Date().toISOString(),
597
+ });
598
+ } catch {
599
+ // Diagnostic persistence must never replace the original startup failure.
600
+ }
601
+ await this.stop(reason, message);
473
602
  throw error;
474
603
  }
475
604
  }
@@ -479,6 +608,7 @@ export class CanonicalForgeRuntime {
479
608
  if (stage === 'ownership') return 'RUNTIME_OWNERSHIP_CONFLICT';
480
609
  if (stage === 'source') return 'RUNTIME_SOURCE_SNAPSHOT_FAILED';
481
610
  if (stage === 'database') return 'DATABASE_UNAVAILABLE';
611
+ if (stage === 'supervisor') return 'WORKFLOW_SUPERVISOR_INITIALIZATION_FAILED';
482
612
  if (stage === 'scheduler') return 'SCHEDULER_INITIALIZATION_FAILED';
483
613
  if (stage === 'localBridge') return 'LOCAL_BRIDGE_STARTUP_FAILED';
484
614
  if (stage === 'transport') return 'MCP_LISTENER_FAILED';
@@ -525,6 +655,8 @@ export class CanonicalForgeRuntime {
525
655
  this.removeJscSamplingProfilerSignal();
526
656
  // Stop accepting new MCP work before quiescing Scheduler activity, then
527
657
  // release the Controller Home claim only after all in-process services stop.
658
+ await this.workflowSupervisor?.close().catch(() => undefined);
659
+ this.workflowSupervisor = undefined;
528
660
  await this.transport?.close().catch(() => undefined);
529
661
  await this.dependencies.stopLightweightProcesses(this.config.controllerHome).catch(() => undefined);
530
662
  await this.dependencies.stopContextReadHelpers().catch(() => undefined);
@@ -1,11 +1,13 @@
1
1
  import {
2
2
  bindControllerSessionBinding,
3
+ getRequirementControllerRoundRelay,
3
4
  type ControllerBinding,
4
5
  type ControllerHost,
5
6
  type ControllerSession,
6
7
  } from '../../../packages/kernel/controller/api/index';
7
- import { createChatgptControllerHost } from '../../../adapters/chatgpt/controller-host';
8
8
  import { upsertChatgptControllerBinding } from '../../../adapters/chatgpt/controller-binding-store';
9
+ import { getWorkContract } from '../../../packages/kernel/work/api/index';
10
+ import { inheritWorkflowSupervisorConversationBinding } from './workflow-supervisor-composition';
9
11
  import { getChatgptWorkConversationBinding } from '../../../adapters/chatgpt/work-conversation-binding-store';
10
12
  import { createProcessControllerHost } from '../../../adapters/controller-process/controller-host';
11
13
  import { upsertProcessControllerBinding, type ProcessControllerType } from '../../../adapters/controller-process/binding-store';
@@ -22,9 +24,13 @@ export function ensureScheduledControllerBinding(
22
24
  workId: input.workId, sessionId: input.session.sessionId,
23
25
  browserSessionId: durable?.latestBrowserSessionId ?? (typeof input.args.browser_session_id === 'string' ? input.args.browser_session_id : undefined),
24
26
  conversationUrl: durable?.conversationUrl ?? (typeof input.args.conversation_url === 'string' ? input.args.conversation_url : undefined),
27
+ authorizationGrantRefs: [
28
+ ...(durable?.authorizationGrantRefs ?? []),
29
+ ...(Array.isArray(input.args.authorization_grant_refs) ? input.args.authorization_grant_refs.map(String) : []),
30
+ ].map(value => value.trim()).filter(Boolean).filter((value, index, values) => values.indexOf(value) === index),
25
31
  title: input.scheduleName,
26
32
  model: typeof input.args.model === 'string' ? input.args.model : 'gpt-5.6',
27
- reasoning: input.args.reasoning === 'medium' || input.args.reasoning === 'xhigh' ? input.args.reasoning : 'high',
33
+ reasoning: input.args.reasoning === 'medium' || input.args.reasoning === 'high' || input.args.reasoning === 'xhigh' ? input.args.reasoning : 'medium',
28
34
  tabPolicy: input.args.tab_policy === 'reuse' || input.args.tab_policy === 'new' ? input.args.tab_policy : 'auto',
29
35
  timeoutMs: typeof input.args.timeout_ms === 'number' ? input.args.timeout_ms : undefined,
30
36
  }).binding;
@@ -43,9 +49,28 @@ export function ensureScheduledControllerBinding(
43
49
  return binding;
44
50
  }
45
51
 
52
+ export function ensureScheduledControllerBindingForWork(
53
+ options: { controllerHome: string; repoId: string },
54
+ input: { workId: string; session: ControllerSession; scheduleName?: string; args: Record<string, unknown> },
55
+ ): ControllerBinding {
56
+ if (input.session.controllerType === 'chatgpt') {
57
+ const work = getWorkContract(options, input.workId);
58
+ if (work?.requirementId && !getChatgptWorkConversationBinding(options, input.workId)) {
59
+ const requirementRelay = getRequirementControllerRoundRelay(options, work.requirementId);
60
+ if (requirementRelay?.originWorkId && requirementRelay.originWorkId !== input.workId) {
61
+ inheritWorkflowSupervisorConversationBinding(options, requirementRelay.originWorkId, input.workId);
62
+ }
63
+ }
64
+ }
65
+ return ensureScheduledControllerBinding(options, input);
66
+ }
67
+
46
68
  export function controllerHostForScheduledBinding(
47
69
  options: { controllerHome: string; repoId: string; repoRoot: string },
48
70
  binding: ControllerBinding,
49
71
  ): ControllerHost {
50
- return binding.hostKind === 'chatgpt' ? createChatgptControllerHost(options) : createProcessControllerHost(options);
72
+ if (binding.hostKind === 'chatgpt') {
73
+ throw new Error('CHATGPT_CONTROLLER_HOST_SUPERVISOR_OWNED');
74
+ }
75
+ return createProcessControllerHost(options);
51
76
  }
@@ -4,6 +4,7 @@ import { spawn, type ChildProcess } from 'child_process';
4
4
  import { loadRuntimeReleaseManifest } from './release-manifest';
5
5
  import { readRuntimeReleaseAuthority } from './release-store';
6
6
  import { readForgeRuntimeServiceConfig } from './service';
7
+ import { runtimeAuthorityFreeEnvironment } from '../shared/process-environment';
7
8
 
8
9
  export interface ForgeRuntimeServiceCommand {
9
10
  executable: string;
@@ -31,10 +32,9 @@ export function resolveForgeRuntimeServiceCommand(controllerHome: string, config
31
32
  '--port', String(config.port),
32
33
  '--auth-token-file', config.authTokenFile,
33
34
  ...activeRuntimeReleaseManifest.arguments,
34
- ...(config.exclusiveWorkId ? ['--exclusive-work-id', config.exclusiveWorkId] : []),
35
35
  ],
36
36
  env: {
37
- ...process.env,
37
+ ...runtimeAuthorityFreeEnvironment(process.env),
38
38
  FORGE_CONTROLLER_HOME: home,
39
39
  FORGE_CONTROLLER_RUNTIME_SOURCE_ROOT: releaseRoot,
40
40
  FORGE_RELEASE_PATH: releaseRoot,