@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,26 +1,73 @@
1
1
  import type { CallToolResult } from '../../../packages/protocols/mcp/tool-contract';
2
+ import { FORGE_INSTANCE_SCOPE_KEY } from '../../../src/cli/repositories/controller-home';
2
3
  import type { MultiRepositoryMcpToolContext } from '../multi-repository';
3
4
  import { buildWorkspaceAuthStatus, prepareWorkspaceAuthLogin, summarizePluginForLowInterception } from '../../../src/runtime/safe-tooling';
4
5
  import {
5
6
  assistantPluginScope,
6
- controllerPluginRepository,
7
7
  getAssistantPluginManifest,
8
+ getControllerPluginManifest,
8
9
  listAssistantPluginManifests,
10
+ listControllerPluginManifests,
9
11
  } from '../../../src/runtime/plugins/store';
10
12
  import { executeAssistantPluginActionApplication } from '../../../src/runtime/plugins/action-application';
11
13
  import { mcpPluginExecutionOrigin } from '../../../src/runtime/plugins/execution-origin';
12
14
  import type { AssistantPluginManifest } from '../../../src/runtime/plugins/types';
13
15
  import { result, resultWithPluginArtifactImages } from './result-adapter';
16
+ import { boundedRuntimeResult } from './bounded-result-runtime';
14
17
  import { selected } from './shared-adapter';
15
18
 
16
- function pluginRepository(
19
+ type PluginTransportScope =
20
+ | { kind: 'controller' }
21
+ | { kind: 'repository'; repository: ReturnType<typeof selected> };
22
+
23
+ function explicitRepositoryContextRequested(args: Record<string, unknown>): boolean {
24
+ return (typeof args.repo_id === 'string' && Boolean(args.repo_id.trim()))
25
+ || (typeof args.checkout_id === 'string' && Boolean(args.checkout_id.trim()));
26
+ }
27
+
28
+ function pluginTransportScope(
17
29
  ctx: MultiRepositoryMcpToolContext,
18
30
  args: Record<string, unknown>,
19
31
  pluginId: string,
20
- ) {
21
- return assistantPluginScope(pluginId, ctx.controllerHome) === 'controller'
22
- ? controllerPluginRepository(ctx.controllerHome)
23
- : selected(ctx, args);
32
+ ): PluginTransportScope {
33
+ const explicitRepoId = typeof args.repo_id === 'string' ? args.repo_id.trim() : '';
34
+ if (explicitRepoId === '__controller__') {
35
+ throw new Error('PLUGIN_CONTROLLER_REPOSITORY_SENTINEL_RETIRED: controller-scoped plugins no longer use a synthetic repository id');
36
+ }
37
+ const scope = assistantPluginScope(pluginId, ctx.controllerHome);
38
+ if (scope === 'controller') return { kind: 'controller' };
39
+ if (scope === 'controller_with_repository_overlay') {
40
+ return explicitRepositoryContextRequested(args)
41
+ ? { kind: 'repository', repository: selected(ctx, args) }
42
+ : { kind: 'controller' };
43
+ }
44
+ return { kind: 'repository', repository: selected(ctx, args) };
45
+ }
46
+
47
+ function pluginManifestForScope(
48
+ ctx: MultiRepositoryMcpToolContext,
49
+ scope: PluginTransportScope,
50
+ pluginId: string,
51
+ ): AssistantPluginManifest {
52
+ return scope.kind === 'controller'
53
+ ? getControllerPluginManifest(ctx.controllerHome, pluginId)
54
+ : getAssistantPluginManifest(ctx.controllerHome, scope.repository, pluginId);
55
+ }
56
+
57
+ function pluginScopeLabel(scope: PluginTransportScope): 'controller' | 'repository' {
58
+ return scope.kind;
59
+ }
60
+
61
+ function detailArgumentsForScope(
62
+ scope: PluginTransportScope,
63
+ pluginId: string,
64
+ actionId?: string,
65
+ ): Record<string, unknown> {
66
+ return {
67
+ ...(scope.kind === 'repository' ? { repo_id: scope.repository.repoId } : {}),
68
+ capability_id: actionId ? `plugin.${pluginId}.${actionId}` : `plugin.${pluginId}`,
69
+ detail_level: 'detail',
70
+ };
24
71
  }
25
72
 
26
73
  function summarizePlugin(manifest: AssistantPluginManifest): Record<string, unknown> {
@@ -93,20 +140,17 @@ export async function callPluginAdapter(
93
140
  ): Promise<CallToolResult | undefined> {
94
141
  switch (name) {
95
142
  case 'list_plugins': {
96
- const controllerRepository = controllerPluginRepository(ctx.controllerHome);
97
- const controllerPlugins = listAssistantPluginManifests(ctx.controllerHome, controllerRepository, {
143
+ const controllerPlugins = listControllerPluginManifests(ctx.controllerHome, {
98
144
  forceRefresh: true,
99
145
  }).map(summarizePlugin);
100
146
  let repositoryPlugins: ReturnType<typeof summarizePlugin>[] = [];
101
147
  let repositoryId: string | undefined;
102
- try {
148
+ if (explicitRepositoryContextRequested(args)) {
103
149
  const repository = selected(ctx, args);
104
150
  repositoryId = repository.repoId;
105
151
  repositoryPlugins = listAssistantPluginManifests(ctx.controllerHome, repository, {
106
152
  forceRefresh: true,
107
153
  }).map(summarizePlugin);
108
- } catch (error) {
109
- if (typeof args.repo_id === 'string' && args.repo_id.trim()) throw error;
110
154
  }
111
155
  return result({
112
156
  scope: repositoryPlugins.length > 0 ? 'combined' : 'controller',
@@ -117,16 +161,16 @@ export async function callPluginAdapter(
117
161
  }
118
162
  case 'get_plugin': {
119
163
  const pluginId = String(args.plugin_id ?? '').trim();
120
- const repository = pluginRepository(ctx, args, pluginId);
164
+ const scope = pluginTransportScope(ctx, args, pluginId);
121
165
  return result({
122
- scope: repository.repoId === '__controller__' ? 'controller' : 'repository',
123
- plugin: summarizePlugin(getAssistantPluginManifest(ctx.controllerHome, repository, pluginId)),
166
+ scope: pluginScopeLabel(scope),
167
+ plugin: summarizePlugin(pluginManifestForScope(ctx, scope, pluginId)),
124
168
  });
125
169
  }
126
170
  case 'plugin_action_execute': {
127
171
  const pluginId = String(args.plugin_id ?? '').trim();
128
172
  const workId = typeof args.work_id === 'string' && args.work_id.trim() ? args.work_id.trim() : undefined;
129
- const repository = pluginRepository(ctx, args, pluginId);
173
+ const scope = pluginTransportScope(ctx, args, pluginId);
130
174
  const workRepository = workId ? selected(ctx, args) : undefined;
131
175
  const actionId = String(args.action_id ?? '').trim();
132
176
  const requestId = String(args.request_id ?? '').trim();
@@ -148,14 +192,25 @@ export async function callPluginAdapter(
148
192
  };
149
193
  const application = await executeAssistantPluginActionApplication({
150
194
  controllerHome: ctx.controllerHome,
151
- repository,
195
+ scope: scope.kind === 'controller'
196
+ ? { kind: 'controller' }
197
+ : { kind: 'repository', repository: scope.repository },
152
198
  request,
153
- interactiveWaitMs: typeof args.interactive_wait_ms === 'number' ? args.interactive_wait_ms : 750,
154
- wait: args.wait === true,
199
+ interactiveWaitMs: args.apply_mode === 'async' ? 0 : (typeof args.interactive_wait_ms === 'number' ? args.interactive_wait_ms : 750),
200
+ wait: args.apply_mode === 'async' ? false : args.wait === true,
155
201
  waitMs: typeof args.wait_ms === 'number' ? args.wait_ms : 15_000,
156
202
  });
157
203
 
158
204
  if (application.kind === 'direct_read') {
205
+ const resultScopeRepoId = scope.kind === 'repository' ? scope.repository.repoId : FORGE_INSTANCE_SCOPE_KEY;
206
+ const boundedPluginResult = boundedRuntimeResult({
207
+ controllerHome: ctx.controllerHome,
208
+ repoId: resultScopeRepoId,
209
+ sessionId: ctx.sessionId,
210
+ principalId: ctx.principalId,
211
+ controllerInstanceId: ctx.controllerInstanceId,
212
+ workId,
213
+ }, application.result);
159
214
  const value = {
160
215
  accepted: true,
161
216
  direct: true,
@@ -166,22 +221,37 @@ export async function callPluginAdapter(
166
221
  risk: application.action.risk,
167
222
  confirmation: application.action.confirmation,
168
223
  },
169
- scope: repository.repoId === '__controller__' ? 'controller' : 'repository',
170
- result: application.result,
224
+ scope: pluginScopeLabel(scope),
225
+ requestId: application.receipt.requestId,
226
+ observationReceiptId: application.receipt.receiptId,
227
+ evidenceRef: application.receipt.receiptId,
228
+ resultDigest: application.receipt.resultDigest,
229
+ result: boundedPluginResult.value,
171
230
  detail: {
172
231
  tool: 'rh_context',
173
232
  arguments: {
174
- ...(repository.repoId === '__controller__' ? {} : { repo_id: repository.repoId }),
175
- capability_id: `plugin.${pluginId}.${actionId}`,
176
- detail_level: 'detail',
233
+ ...detailArgumentsForScope(scope, pluginId, actionId),
177
234
  },
178
235
  },
179
- next: 'Continue with the returned bounded result; use rh_context capability detail only when the typed action schema/policy is needed.',
236
+ next: 'Continue with the returned bounded result. The compact observationReceiptId/evidenceRef may support model-selected learning without creating Work or effect replay state; use rh_context capability detail only when the typed action schema/policy is needed.',
180
237
  };
181
- return resultWithPluginArtifactImages(value, ctx.controllerHome, repository.repoId, application.result);
238
+ return resultWithPluginArtifactImages(
239
+ value,
240
+ ctx.controllerHome,
241
+ resultScopeRepoId,
242
+ application.result,
243
+ );
182
244
  }
183
245
 
184
246
  if (application.kind === 'direct_non_persistent') {
247
+ const boundedPluginResult = boundedRuntimeResult({
248
+ controllerHome: ctx.controllerHome,
249
+ repoId: scope.kind === 'repository' ? scope.repository.repoId : FORGE_INSTANCE_SCOPE_KEY,
250
+ sessionId: ctx.sessionId,
251
+ principalId: ctx.principalId,
252
+ controllerInstanceId: ctx.controllerInstanceId,
253
+ workId,
254
+ }, application.result);
185
255
  return result({
186
256
  accepted: true,
187
257
  direct: true,
@@ -194,27 +264,25 @@ export async function callPluginAdapter(
194
264
  risk: application.action.risk,
195
265
  confirmation: application.action.confirmation,
196
266
  },
197
- scope: repository.repoId === '__controller__' ? 'controller' : 'repository',
267
+ scope: pluginScopeLabel(scope),
198
268
  requestId,
199
- result: application.result,
269
+ result: boundedPluginResult.value,
200
270
  detail: {
201
271
  tool: 'rh_context',
202
272
  arguments: {
203
- ...(repository.repoId === '__controller__' ? {} : { repo_id: repository.repoId }),
204
- capability_id: `plugin.${pluginId}.${actionId}`,
205
- detail_level: 'detail',
273
+ ...detailArgumentsForScope(scope, pluginId, actionId),
206
274
  },
207
275
  },
208
276
  next: 'This protected action completed inline without durable replay state. Use the returned result only for the immediate next protected action.',
209
277
  });
210
278
  }
211
279
 
212
- if (application.kind === 'lightweight_running') {
280
+ if (application.kind === 'managed_running') {
213
281
  return result({
214
282
  accepted: true,
215
283
  direct: false,
216
- durable: false,
217
- mode: 'lightweight_process',
284
+ durable: true,
285
+ mode: 'process_managed',
218
286
  plugin: summarizePluginActionReceipt(application.manifest),
219
287
  action: application.action ? {
220
288
  actionId: application.action.actionId,
@@ -222,21 +290,22 @@ export async function callPluginAdapter(
222
290
  confirmation: application.action.confirmation,
223
291
  requiredConfirmationText: application.action.requiredConfirmationText,
224
292
  } : { actionId },
225
- scope: 'repository',
293
+ scope: pluginScopeLabel(scope),
226
294
  requestId,
227
295
  process: application.process,
228
296
  resultRef: { kind: 'process_logs', processId: application.process.processId },
229
- next: 'The typed plugin action is isolated from the Canonical Runtime. Use process_wait on processId; after completion, call plugin_action_execute again with the same request_id to retrieve the deduplicated structured receipt.',
297
+ observation: { status: 'in_progress', outcome: 'unknown_until_process_terminal', retryPolicy: 'reattach_same_request_id' },
298
+ next: 'Execution is durably detached from this MCP stream. Observe processId/resultRef; after terminal completion, call plugin_action_execute with the same request_id to retrieve the deduplicated structured receipt. Never redispatch with a new request id because observation was interrupted.',
230
299
  });
231
300
  }
232
301
 
233
- if (application.kind === 'lightweight_failed') {
302
+ if (application.kind === 'managed_failed') {
234
303
  const handle = application.process;
235
304
  return result({
236
305
  accepted: true,
237
306
  direct: false,
238
- durable: false,
239
- mode: 'lightweight_process',
307
+ durable: true,
308
+ mode: 'process_managed',
240
309
  requestId,
241
310
  process: handle,
242
311
  error: {
@@ -260,7 +329,7 @@ export async function callPluginAdapter(
260
329
  confirmation: submitted.action.confirmation,
261
330
  requiredConfirmationText: submitted.action.requiredConfirmationText,
262
331
  },
263
- scope: repository.repoId === '__controller__' ? 'controller' : 'repository',
332
+ scope: pluginScopeLabel(scope),
264
333
  receiptId: submitted.receipt.receiptId,
265
334
  requestId: submitted.receipt.requestId,
266
335
  ...(submitted.receipt.workId ? { workId: submitted.receipt.workId } : {}),
@@ -269,14 +338,17 @@ export async function callPluginAdapter(
269
338
  detail: {
270
339
  tool: 'rh_context',
271
340
  arguments: {
272
- ...(repository.repoId === '__controller__' ? {} : { repo_id: repository.repoId }),
273
- capability_id: `plugin.${pluginId}.${actionId}`,
274
- detail_level: 'detail',
341
+ ...detailArgumentsForScope(scope, pluginId, actionId),
275
342
  },
276
343
  },
277
344
  next: 'Continue with the returned bounded plugin result; use rh_context capability detail only when the typed action schema/policy is needed.',
278
345
  };
279
- return resultWithPluginArtifactImages(value, ctx.controllerHome, repository.repoId, compactResult);
346
+ return resultWithPluginArtifactImages(
347
+ value,
348
+ ctx.controllerHome,
349
+ scope.kind === 'repository' ? scope.repository.repoId : FORGE_INSTANCE_SCOPE_KEY,
350
+ compactResult,
351
+ );
280
352
  }
281
353
  case 'workspace_auth_status': {
282
354
  const repository = selected(ctx, args);
@@ -292,8 +364,8 @@ export async function callPluginAdapter(
292
364
  }
293
365
  case 'toolchain_plugin_summary': {
294
366
  const pluginId = String(args.plugin_id ?? '').trim();
295
- const repository = pluginRepository(ctx, args, pluginId);
296
- const manifest = getAssistantPluginManifest(ctx.controllerHome, repository, pluginId);
367
+ const scope = pluginTransportScope(ctx, args, pluginId);
368
+ const manifest = pluginManifestForScope(ctx, scope, pluginId);
297
369
  return result({
298
370
  plugin: summarizePluginForLowInterception(manifest),
299
371
  nonOpaque: true,
@@ -11,11 +11,20 @@ import type { McpToolDefinition, CallToolResult } from '../../../packages/protoc
11
11
  import type { MultiRepositoryMcpToolContext } from '../multi-repository';
12
12
  import {
13
13
  cancelRepositoryCommandProcess,
14
+ executeHostCommand,
14
15
  getRepositoryCommandProcess,
15
16
  readRepositoryCommandProcessLogs,
16
17
  waitRepositoryCommandProcess,
17
18
  } from '../../../src/runtime/execution/process-runtime';
18
19
  import { redactSensitiveText, redactSensitiveValue } from '../../../src/runtime/evidence/sensitive-output';
20
+ import { getProcessRecord } from '../../../src/runtime/execution/process-runtime/store';
21
+ import { forgeInstanceIdFor, readProcessHandleIndexEntry } from '../../../src/runtime/execution/process-runtime/handle-index';
22
+ import { isForgeInstanceProcessScopeKey, isRepositoryProcessScopeKey, processScopeKeyForHandle } from '../../../src/runtime/execution/process-runtime/process-scope';
23
+ import { reconcileTerminalWorkVerifications } from '../../../src/runtime/control-plane/execution/work-verification-service';
24
+ import type { WorkHandleState } from '../../../src/runtime/control-plane/execution/work-handle-store';
25
+ import { findControlPlaneRecordsByKey } from '../../../src/runtime/control-plane/persistence/sqlite-store';
26
+ import { sanitizeFileComponent } from '../../../src/runtime/shared/json-files';
27
+ import { selected, stringList } from './shared-adapter';
19
28
 
20
29
  function definition(
21
30
  name: string,
@@ -40,7 +49,7 @@ function definition(
40
49
 
41
50
  const repoIdProp = {
42
51
  type: 'string',
43
- description: 'Repository or ephemeral workspace scope id returned by the originating command. Process must belong to this scope.',
52
+ description: 'Optional repository or ephemeral workspace scope id returned by the originating command. When omitted, the process handle resolves its own recorded execution target.',
44
53
  };
45
54
  const processIdProp = {
46
55
  type: 'string',
@@ -48,6 +57,23 @@ const processIdProp = {
48
57
  };
49
58
 
50
59
  export const processToolDefinitions: McpToolDefinition[] = [
60
+ definition(
61
+ 'process_exec',
62
+ 'Execute one command on the Forge instance itself: cwd is an execution argument and no repository, checkout, or Work is required. Requires an explicit broad `process:exec` canonical Grant for this ForgeInstance; Forge does not parse the command to prove path safety. Returns a process handle; attach with process_get/process_wait/process_logs/process_cancel using the handle only.',
63
+ {
64
+ command: { type: 'array', items: { type: 'string' }, maxItems: 512, description: 'Typed argv command; command[0] is the executable. Mutually exclusive with shell_command.' },
65
+ shell_command: { type: 'string', maxLength: 32_000, description: 'Explicit broad shell form. Mutually exclusive with command. Never parsed for path safety.' },
66
+ cwd: { type: 'string', description: 'Optional absolute working directory. With work_id and no cwd, Forge uses that Work handle\'s exact workspace/worktree as a convenience default; this never grants permission and explicit authorized cwd may be elsewhere.' },
67
+ timeout_ms: { type: 'number' },
68
+ interactive_wait_ms: { type: 'number' },
69
+ max_output_bytes: { type: 'number' },
70
+ request_id: { type: 'string', description: 'Stable invocation id. A retry with the same id attaches to the existing process instead of re-executing.' },
71
+ work_id: { type: 'string', description: 'Optional Work provenance; Work is never required to run a host command.' },
72
+ },
73
+ [],
74
+ false,
75
+ true,
76
+ ),
51
77
  definition(
52
78
  'run_check',
53
79
  'Run one focused repository check, or launch one resource-compatible check wave, through Process Runtime. Use check_id for the existing single-check behavior or check_ids for a batch; do not send both. Batch mode validates the existing check-scheduling resource model and starts every check in one compatible wave concurrently without waiting for completion or creating a second scheduler. Cross-wave, invalid, release, and multi-phase batches fail closed. Long ordinary checks return managed handles; attach only at a real dependency boundary.',
@@ -74,7 +100,7 @@ export const processToolDefinitions: McpToolDefinition[] = [
74
100
  repo_id: repoIdProp,
75
101
  process_id: processIdProp,
76
102
  },
77
- ['repo_id', 'process_id'],
103
+ ['process_id'],
78
104
  true,
79
105
  ),
80
106
  definition(
@@ -85,7 +111,7 @@ export const processToolDefinitions: McpToolDefinition[] = [
85
111
  process_id: processIdProp,
86
112
  timeout_ms: { type: 'number', description: 'Max wait milliseconds (default 15000).' },
87
113
  },
88
- ['repo_id', 'process_id'],
114
+ ['process_id'],
89
115
  true,
90
116
  ),
91
117
  definition(
@@ -96,7 +122,7 @@ export const processToolDefinitions: McpToolDefinition[] = [
96
122
  process_id: processIdProp,
97
123
  max_bytes: { type: 'number', description: 'Max tail bytes per stream (default 32KiB).' },
98
124
  },
99
- ['repo_id', 'process_id'],
125
+ ['process_id'],
100
126
  true,
101
127
  ),
102
128
  definition(
@@ -106,7 +132,7 @@ export const processToolDefinitions: McpToolDefinition[] = [
106
132
  repo_id: repoIdProp,
107
133
  process_id: processIdProp,
108
134
  },
109
- ['repo_id', 'process_id'],
135
+ ['process_id'],
110
136
  false,
111
137
  true,
112
138
  ),
@@ -114,6 +140,33 @@ export const processToolDefinitions: McpToolDefinition[] = [
114
140
 
115
141
  const processToolNames = new Set(processToolDefinitions.map((tool) => tool.name));
116
142
  const processAttachmentToolNames = new Set(['process_get', 'process_wait', 'process_logs', 'process_cancel']);
143
+
144
+ function reconcileAttachedWorkVerification(
145
+ ctx: MultiRepositoryMcpToolContext,
146
+ repoId: string,
147
+ processId: string,
148
+ handle: { completed?: boolean; workId?: string },
149
+ ): Record<string, unknown> | undefined {
150
+ if (handle.completed !== true || !handle.workId) return undefined;
151
+ const record = getProcessRecord(ctx.controllerHome, repoId, processId);
152
+ if (record?.origin?.workVerificationSnapshot !== true) return undefined;
153
+ try {
154
+ const repository = selected(ctx, { repo_id: repoId, checkout_id: record.checkoutId });
155
+ const reconciled = reconcileTerminalWorkVerifications({
156
+ controllerHome: ctx.controllerHome,
157
+ repository,
158
+ workId: handle.workId,
159
+ });
160
+ return {
161
+ workId: handle.workId,
162
+ processId,
163
+ status: reconciled.reconciledProcessIds.includes(processId) ? 'reconciled' : 'already_current_or_non_authoritative',
164
+ reconciledProcessIds: reconciled.reconciledProcessIds,
165
+ };
166
+ } catch {
167
+ return { workId: handle.workId, processId, status: 'non_authoritative' };
168
+ }
169
+ }
117
170
  // A long-lived MCP wait can monopolize shared Runtime request/transport capacity
118
171
  // even though the underlying Process wait is asynchronous. Keep public waits
119
172
  // short and return a normal running snapshot; the Process continues unchanged
@@ -162,21 +215,58 @@ function failure(error: unknown): CallToolResult {
162
215
  function requireRepoAndProcess(
163
216
  ctx: MultiRepositoryMcpToolContext,
164
217
  args: Record<string, unknown>,
165
- ): { repoId: string; processId: string } {
218
+ ): { repoId?: string; processId: string; handle: NonNullable<ReturnType<typeof getRepositoryCommandProcess>> } {
166
219
  const repoId = typeof args.repo_id === 'string' ? args.repo_id.trim() : '';
167
220
  const processId = typeof args.process_id === 'string' ? args.process_id.trim() : '';
168
- if (!repoId) throw new Error('REPOSITORY_ID_REQUIRED: repo_id is required for process tools');
169
221
  if (!processId) throw new Error('PROCESS_ID_REQUIRED: process_id is required for process tools');
222
+ assertProcessHandleAccess(ctx, processId);
170
223
 
171
- // The Process handle is the scope authority. Ephemeral workspace targets are
172
- // intentionally not registered in Repository Registry, so requiring a live
173
- // repository record here would make their returned managed handles impossible
174
- // to resume. Exact repo/workspace scope + process id still fails closed.
175
- const handle = getRepositoryCommandProcess(ctx.controllerHome, repoId, processId);
224
+ // The Process handle is the scope authority. An explicit repo_id is validated
225
+ // against the handle's recorded target; when it is omitted the handle index
226
+ // resolves the target so attachment never needs placement replay. Ephemeral
227
+ // workspace targets are intentionally not registered in Repository Registry,
228
+ // so requiring a live repository record here would make their returned
229
+ // managed handles impossible to resume.
230
+ const recordedScopeKey = processScopeKeyForHandle(ctx.controllerHome, processId);
231
+ // A ForgeInstance-scoped handle keeps its instance target even when a client
232
+ // always sends repo_id; the index remains the target authority.
233
+ const effectiveScopeKey = recordedScopeKey && isForgeInstanceProcessScopeKey(recordedScopeKey)
234
+ ? recordedScopeKey
235
+ : (repoId || recordedScopeKey);
236
+ const handle = getRepositoryCommandProcess(ctx.controllerHome, effectiveScopeKey, processId);
176
237
  if (!handle) {
177
- throw new Error(`PROCESS_NOT_FOUND: process ${processId} is not registered under repo ${repoId}`);
238
+ throw new Error(repoId
239
+ ? `PROCESS_NOT_FOUND: process ${processId} is not registered under repo ${repoId}`
240
+ : `PROCESS_NOT_FOUND: ${processId}`);
241
+ }
242
+ const resolvedScopeKey = recordedScopeKey && isForgeInstanceProcessScopeKey(recordedScopeKey) ? recordedScopeKey : (repoId || recordedScopeKey);
243
+ const resolvedRepoId = resolvedScopeKey && isRepositoryProcessScopeKey(resolvedScopeKey) ? resolvedScopeKey : undefined;
244
+ return { repoId: resolvedRepoId || undefined, processId, handle };
245
+ }
246
+
247
+ /**
248
+ * A process handle id locates a record; it never authorizes attachment by
249
+ * itself. Instance-level handles are principal-bound and ForgeInstance-bound,
250
+ * and a recorded repository principal is enforced when the caller presents one.
251
+ */
252
+ function assertProcessHandleAccess(ctx: MultiRepositoryMcpToolContext, processId: string): void {
253
+ const entry = readProcessHandleIndexEntry(ctx.controllerHome, processId);
254
+ if (!entry) return;
255
+ const caller = ctx.principalId?.trim();
256
+ const recorded = entry.principalId?.trim();
257
+ if (entry.target.scope === 'forge_instance') {
258
+ const servingInstance = forgeInstanceIdFor(ctx.controllerHome);
259
+ if (entry.target.forgeInstanceId && servingInstance && entry.target.forgeInstanceId !== servingInstance) {
260
+ throw new Error(`PROCESS_HANDLE_INSTANCE_MISMATCH: process ${processId} belongs to ForgeInstance ${entry.target.forgeInstanceId}`);
261
+ }
262
+ if (!recorded) throw new Error(`PROCESS_HANDLE_PRINCIPAL_UNBOUND: process ${processId} has no recorded principal`);
263
+ if (!caller) throw new Error(`PROCESS_HANDLE_PRINCIPAL_REQUIRED: process ${processId} requires an authenticated principal`);
264
+ if (recorded !== caller) throw new Error(`PROCESS_HANDLE_PRINCIPAL_MISMATCH: process ${processId} is owned by another principal`);
265
+ return;
266
+ }
267
+ if (recorded && caller && recorded !== caller) {
268
+ throw new Error(`PROCESS_HANDLE_PRINCIPAL_MISMATCH: process ${processId} is owned by another principal`);
178
269
  }
179
- return { repoId, processId };
180
270
  }
181
271
 
182
272
  function handleToPayload(handle: NonNullable<ReturnType<typeof getRepositoryCommandProcess>>): Record<string, unknown> {
@@ -214,19 +304,23 @@ export async function callProcessTool(
214
304
  name: string,
215
305
  args: Record<string, unknown>,
216
306
  ): Promise<CallToolResult | undefined> {
307
+ if (name === 'process_exec') return callProcessExecTool(ctx, args);
217
308
  // run_check shares this module's public schema, but its execution authority is
218
309
  // the Gateway check facade in router.ts. Only attachment/lifecycle operations
219
310
  // consume an existing process_id here.
220
311
  if (!processAttachmentToolNames.has(name)) return undefined;
221
312
  try {
222
- const { repoId, processId } = requireRepoAndProcess(ctx, args);
313
+ const { repoId, processId, handle: attachedHandle } = requireRepoAndProcess(ctx, args);
314
+ const scopePayload = repoId ? { repoId } : {};
223
315
  switch (name) {
224
316
  case 'process_get': {
225
- const handle = getRepositoryCommandProcess(ctx.controllerHome, repoId, processId);
226
- if (!handle) throw new Error(`PROCESS_NOT_FOUND: ${processId}`);
317
+ const workVerificationReconciliation = repoId
318
+ ? reconcileAttachedWorkVerification(ctx, repoId, processId, attachedHandle)
319
+ : undefined;
227
320
  return result({
228
- repoId,
229
- process: handleToPayload(handle),
321
+ ...scopePayload,
322
+ process: handleToPayload(attachedHandle),
323
+ ...(workVerificationReconciliation ? { workVerificationReconciliation } : {}),
230
324
  });
231
325
  }
232
326
  case 'process_wait': {
@@ -241,9 +335,13 @@ export async function callProcessTool(
241
335
  const handle = await waitRepositoryCommandProcess(ctx.controllerHome, repoId, processId, {
242
336
  timeoutMs: Math.min(requestedWaitMs, attachBudgetMs),
243
337
  });
338
+ const workVerificationReconciliation = repoId
339
+ ? reconcileAttachedWorkVerification(ctx, repoId, processId, handle)
340
+ : undefined;
244
341
  return result({
245
- repoId,
342
+ ...scopePayload,
246
343
  process: handleToPayload(handle),
344
+ ...(workVerificationReconciliation ? { workVerificationReconciliation } : {}),
247
345
  synchronization: handle.completed === true ? 'terminal_result_available' : 'continue_independent_work',
248
346
  waitedMs: Date.now() - startedAt,
249
347
  requestedWaitMs,
@@ -258,7 +356,7 @@ export async function callProcessTool(
258
356
  const logs = readRepositoryCommandProcessLogs(ctx.controllerHome, repoId, processId, maxBytes);
259
357
  if (!logs) throw new Error(`PROCESS_NOT_FOUND: ${processId}`);
260
358
  return result({
261
- repoId,
359
+ ...scopePayload,
262
360
  processId,
263
361
  stdout: logs.stdout,
264
362
  stderr: logs.stderr,
@@ -271,7 +369,7 @@ export async function callProcessTool(
271
369
  case 'process_cancel': {
272
370
  const handle = await cancelRepositoryCommandProcess(ctx.controllerHome, repoId, processId);
273
371
  return result({
274
- repoId,
372
+ ...scopePayload,
275
373
  process: handleToPayload(handle),
276
374
  cancelled: handle.cancelled === true || handle.status === 'cancelled' || handle.status === 'completed_unknown',
277
375
  });
@@ -284,6 +382,76 @@ export async function callProcessTool(
284
382
  }
285
383
  }
286
384
 
385
+ /**
386
+ * `process_exec` — the canonical host-local command lane.
387
+ *
388
+ * Repo-less by construction: the Forge instance is the target and `cwd` is an
389
+ * execution argument. Authorization is one explicit canonical `process:exec`
390
+ * Grant for this instance, enforced in the lane before any spawn.
391
+ */
392
+ function workDefaultCommandCwd(ctx: MultiRepositoryMcpToolContext, workId: string): string | undefined {
393
+ if (!workId) return undefined;
394
+ const matches = findControlPlaneRecordsByKey<WorkHandleState>(ctx.controllerHome, {
395
+ namespace: 'execution_work_handle',
396
+ key: sanitizeFileComponent(workId),
397
+ limit: 2,
398
+ });
399
+ if (matches.length > 1) {
400
+ throw new Error(`WORK_EXECUTION_PLACEMENT_AMBIGUOUS: ${workId} resolves to multiple execution handles`);
401
+ }
402
+ const handle = matches[0]?.value;
403
+ if (!handle) return undefined;
404
+ if (handle.workId !== workId) throw new Error(`WORK_EXECUTION_PLACEMENT_IDENTITY_MISMATCH: ${workId}`);
405
+ const workspace = handle.worktreePath?.trim();
406
+ return workspace || undefined;
407
+ }
408
+
409
+ async function callProcessExecTool(
410
+ ctx: MultiRepositoryMcpToolContext,
411
+ args: Record<string, unknown>,
412
+ ): Promise<CallToolResult> {
413
+ try {
414
+ const command = stringList(args.command);
415
+ const shellCommand = typeof args.shell_command === 'string' && args.shell_command.trim()
416
+ ? args.shell_command
417
+ : undefined;
418
+ if (command.length > 0 && shellCommand) {
419
+ throw new Error('HOST_COMMAND_AMBIGUOUS: provide exactly one of command or shell_command');
420
+ }
421
+ if (command.length === 0 && !shellCommand) {
422
+ throw new Error('HOST_COMMAND_REQUIRED: provide command (argv) or shell_command');
423
+ }
424
+ const requestId = typeof args.request_id === 'string' ? args.request_id.trim() : '';
425
+ const workId = typeof args.work_id === 'string' ? args.work_id.trim() : '';
426
+ const explicitCwd = typeof args.cwd === 'string' ? args.cwd.trim() : '';
427
+ const cwd = explicitCwd || workDefaultCommandCwd(ctx, workId) || '';
428
+ const executed = await executeHostCommand({
429
+ controllerHome: ctx.controllerHome,
430
+ principalId: ctx.principalId ?? '',
431
+ ...(command.length > 0 ? { command } : {}),
432
+ ...(shellCommand ? { shellCommand } : {}),
433
+ cwd,
434
+ ...(typeof args.timeout_ms === 'number' ? { timeoutMs: args.timeout_ms } : {}),
435
+ ...(typeof args.interactive_wait_ms === 'number' ? { interactiveWaitMs: args.interactive_wait_ms } : {}),
436
+ ...(typeof args.max_output_bytes === 'number' ? { maxOutputBytes: args.max_output_bytes } : {}),
437
+ ...(requestId ? { commandId: requestId } : {}),
438
+ ...(workId ? { workId } : {}),
439
+ });
440
+ return result({
441
+ process: handleToPayload(executed.handle),
442
+ target: {
443
+ scope: 'forge_instance',
444
+ forgeInstanceId: executed.target.forgeInstanceId,
445
+ cwd: executed.target.cwd,
446
+ },
447
+ authorization: { capability: 'process:exec', grantId: executed.target.grantId },
448
+ executionMetrics: executed.metrics,
449
+ });
450
+ } catch (error) {
451
+ return failure(error);
452
+ }
453
+ }
454
+
287
455
  export function isProcessTool(name: string): boolean {
288
456
  return processToolNames.has(name);
289
457
  }