@moretea-labs/forge 1.8.1 → 1.8.2

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 (328) hide show
  1. package/AGENTS.md +5 -2
  2. package/CHANGELOG.md +20 -0
  3. package/README.en.md +24 -3
  4. package/README.md +10 -6
  5. package/README.zh-CN.md +5 -3
  6. package/THIRD_PARTY_NOTICES.md +1 -2
  7. package/adapters/chatgpt/browser-delivery-runtime.ts +5 -3
  8. package/adapters/chatgpt/provider-delivery.ts +1 -1
  9. package/adapters/chatgpt/work-conversation-binding-store.ts +20 -1
  10. package/adapters/computer/chatgpt-extension-target.ts +295 -50
  11. package/adapters/computer/chrome-extension/background.js +227 -71
  12. package/adapters/computer/chrome-extension/content.js +181 -157
  13. package/adapters/computer/chrome-extension/manifest.json +3 -1
  14. package/adapters/computer/desktop-operator-provider.ts +18 -6
  15. package/adapters/computer/interaction-target-authority.ts +39 -9
  16. package/adapters/mcp/access-mode.ts +18 -39
  17. package/adapters/mcp/auth.ts +2 -6
  18. package/adapters/mcp/instructions.ts +2 -2
  19. package/adapters/mcp/multi-repository.ts +7 -28
  20. package/adapters/mcp/runtime-gateway/context-adapter.ts +79 -40
  21. package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +7 -15
  22. package/adapters/mcp/runtime-gateway/execution-tools.ts +7 -13
  23. package/adapters/mcp/runtime-gateway/plugin-adapter.ts +16 -3
  24. package/adapters/mcp/runtime-gateway/process-tools.ts +3 -21
  25. package/adapters/mcp/runtime-gateway/router.ts +3 -5
  26. package/adapters/mcp/runtime-gateway/routing-policy.ts +17 -10
  27. package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +1 -1
  28. package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +14 -9
  29. package/adapters/mcp/runtime-gateway/runtime-tools.ts +1 -5
  30. package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +36 -1
  31. package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +58 -4
  32. package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +7 -3
  33. package/adapters/mcp/runtime-gateway/work-adapter.ts +16 -16
  34. package/adapters/mcp/runtime-gateway/work-input-wire-migration.ts +0 -17
  35. package/adapters/mcp/runtime-gateway/work-semantic-operations.ts +69 -12
  36. package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +26 -2
  37. package/adapters/mcp/server.ts +24 -3
  38. package/adapters/mcp/setup.ts +4 -10
  39. package/adapters/mcp/tool-mapping/access-tools.ts +0 -6
  40. package/adapters/mcp/tool-mapping/legacy-tool-service.ts +672 -2935
  41. package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +1 -1
  42. package/adapters/mcp/tool-mapping/repository-tools.ts +52 -86
  43. package/adapters/mcp/toolset-names.ts +11 -42
  44. package/adapters/mcp/toolset.ts +16 -90
  45. package/{src/cli → adapters}/mcp/transports/AGENTS.md +5 -5
  46. package/{src/cli → adapters}/mcp/transports/CLAUDE.md +5 -5
  47. package/adapters/mcp/transports/http-observation.ts +18 -6
  48. package/adapters/mcp/transports/http-post-lifecycle.ts +19 -0
  49. package/adapters/mcp/transports/http.ts +54 -14
  50. package/adapters/mcp/types.ts +0 -6
  51. package/assets/hooks/lib/session-state.sh +0 -38
  52. package/assets/hooks/post-bash.sh +1 -1
  53. package/assets/hooks/post-tool-observer.sh +0 -5
  54. package/assets/hooks/prompt-guard.sh +0 -55
  55. package/assets/partials/04-project-structure.partial.md +1 -1
  56. package/assets/partials/07-footer.partial.md +1 -1
  57. package/assets/partials-agents/02-operating-mode.partial.md +1 -1
  58. package/assets/partials-agents/08-deep-docs.partial.md +1 -1
  59. package/assets/reference-configs/agentic-development-flow.md +1 -1
  60. package/assets/reference-configs/external-tooling.md +0 -76
  61. package/assets/reference-configs/release-deploy.md +1 -1
  62. package/assets/templates/helpers/architecture-queue.sh +1 -1
  63. package/assets/templates/helpers/check-agent-tooling.sh +1 -327
  64. package/assets/templates/helpers/check-task-workflow.sh +1 -1
  65. package/assets/templates/helpers/ensure-task-workflow.sh +0 -14
  66. package/assets/templates/helpers/migrate-project-template.sh +2 -2
  67. package/assets/workflow-contract.v1.json +0 -2
  68. package/docs/README.md +5 -2
  69. package/docs/architecture/CURRENT.md +114 -30
  70. package/docs/architecture/decisions/20260904-ios-device-migration-baseline.md +42 -0
  71. package/docs/architecture/decisions/20260918-stable-candidate-release-lifecycle.md +15 -2
  72. package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +4 -2
  73. package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +109 -4
  74. package/docs/architecture/decisions/20261009-exact-code-context-discovery.md +19 -0
  75. package/docs/architecture/decisions/20261009-generated-xcode-cache-retention.md +37 -0
  76. package/docs/architecture/decisions/20261011-autonomous-continuation-convergence.md +597 -0
  77. package/docs/architecture/decisions/20261017-edit-session-finalization-reconciliation.md +17 -0
  78. package/docs/architecture/decisions/20261019-retire-host-skills.md +16 -0
  79. package/docs/architecture/diagrams/agentic-dev-plugin-architecture.html +1 -1
  80. package/docs/architecture/domains/public-surface.md +3 -5
  81. package/docs/architecture/domains/verification.md +5 -5
  82. package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +2 -2
  83. package/docs/architecture/requests/2026-09-04-computer-plugin-workflow-taxonomy.md +4 -4
  84. package/docs/architecture/reviews/20261015-code-search-runtime-acceptance.md +75 -0
  85. package/docs/forge-plugin-management.md +14 -2
  86. package/docs/operations/controller-browser-plugin.md +23 -0
  87. package/docs/operations/features.md +6 -7
  88. package/docs/operations/features.zh-CN.md +1 -1
  89. package/docs/operations/github-repository.md +4 -4
  90. package/docs/operations/github-semantic-release-projection.md +20 -0
  91. package/docs/operations/homebrew.md +2 -2
  92. package/docs/operations/mcp-tool-exposure.md +13 -54
  93. package/docs/operations/runtime-performance-diagnostics.md +8 -0
  94. package/docs/operations/standalone-disaster-recovery.md +1 -1
  95. package/docs/tutorials/01-install-and-start.zh-CN.md +1 -1
  96. package/docs/tutorials/03-first-repository-task.md +2 -0
  97. package/docs/wiki/Computer-and-Plugins.md +78 -0
  98. package/docs/wiki/Computer-and-Plugins.zh-CN.md +88 -0
  99. package/docs/wiki/Home.md +16 -2
  100. package/docs/wiki/Implementation.md +24 -12
  101. package/docs/wiki/Installation.md +28 -32
  102. package/docs/wiki/Integrations.md +4 -0
  103. package/docs/wiki/Quick-Start.md +35 -22
  104. package/docs/wiki/Releases-and-Upgrades.md +15 -25
  105. package/docs/wiki/_Sidebar.md +5 -1
  106. package/package.json +1 -12
  107. package/packages/kernel/controller/infrastructure/controller-session-store.ts +63 -38
  108. package/packages/kernel/identity/infrastructure/activity-projection-store.ts +10 -0
  109. package/packages/kernel/scheduler/application/eligibility.ts +4 -1
  110. package/packages/kernel/scheduler/infrastructure/schedule-store.ts +13 -10
  111. package/packages/kernel/work/application/work-service.ts +1 -0
  112. package/packages/kernel/work/domain/repository-completion-receipt.ts +1 -1
  113. package/packages/kernel/work/domain/state-machine.ts +9 -2
  114. package/packages/kernel/work/infrastructure/work-contract-store.ts +28 -1
  115. package/packages/plugin-runtime/browser/provider-registry.ts +12 -36
  116. package/packages/plugin-runtime/computer/conversation-target.ts +17 -7
  117. package/scripts/assemble-template.ts +11 -72
  118. package/scripts/check-mcp-compatibility.ts +55 -74
  119. package/scripts/check-package-identity.mjs +0 -5
  120. package/scripts/check-runtime-architecture.mjs +305 -28
  121. package/scripts/init-project.sh +0 -46
  122. package/scripts/install-ios-hid-toolchain.sh +60 -0
  123. package/scripts/install-standalone-recovery.ts +1 -1
  124. package/scripts/lib/project-init-lib.sh +3 -3
  125. package/scripts/migrate-windows-wsl-controller-home.ts +2 -0
  126. package/scripts/open-source-audit-allowlist.txt +0 -1
  127. package/scripts/run-governed-gate.ts +2 -0
  128. package/scripts/smoke-ios-physical-device.ts +38 -10
  129. package/scripts/smoke-mcp-http-runtime.ts +7 -8
  130. package/scripts/smoke-mcp-tool-surface.ts +27 -41
  131. package/scripts/smoke-workflow-supervisor-chrome-adapter.ts +6 -3
  132. package/scripts/sync-generated-authority.mjs +0 -1
  133. package/src/cli/agent-jobs/executor-health.ts +1 -1
  134. package/src/cli/agent-jobs/integration.ts +2 -2
  135. package/src/cli/chatgpt-browser/file-policy.ts +2 -2
  136. package/src/cli/commands/doctor.ts +1 -143
  137. package/src/cli/commands/global-runtime.ts +3 -196
  138. package/src/cli/commands/init-hook.ts +6 -23
  139. package/src/cli/commands/init.ts +3 -252
  140. package/src/cli/commands/mcp.ts +0 -5
  141. package/src/cli/commands/prompt-guard-decision.ts +0 -2
  142. package/src/cli/commands/recovery.ts +2 -14
  143. package/src/cli/commands/repository.ts +17 -1
  144. package/src/cli/commands/setup-execution.ts +41 -0
  145. package/src/cli/controller/completion-orchestrator.ts +1 -1
  146. package/src/cli/controller/composite-operations.ts +1 -1
  147. package/src/cli/controller/context/instruction-context.ts +1 -1
  148. package/src/cli/controller/context/known-paths.ts +2 -2
  149. package/src/cli/controller/context/query-planning.ts +11 -4
  150. package/src/cli/controller/context/rule-resolution.ts +2 -2
  151. package/src/cli/controller/context/source-materializer.ts +2 -2
  152. package/src/cli/controller/context/structural-provider.ts +84 -0
  153. package/src/cli/controller/context/structural.ts +6 -6
  154. package/src/cli/controller/context/types.ts +8 -9
  155. package/src/cli/controller/context-pack.ts +97 -76
  156. package/src/cli/controller/operational-plan.ts +1 -1
  157. package/src/cli/controller/systemd-user.ts +4 -10
  158. package/src/cli/editing/edit-session.ts +17 -5
  159. package/src/cli/github/github.ts +4 -4
  160. package/src/cli/github/semantic-projection.ts +174 -0
  161. package/src/cli/hook/prompt-intents.ts +0 -9
  162. package/src/cli/index.ts +1 -43
  163. package/src/cli/local-bridge/connector-freshness.ts +1 -12
  164. package/src/cli/local-bridge/console-automations.ts +1 -1
  165. package/src/cli/local-bridge/console-view-models.ts +1 -1
  166. package/src/cli/local-bridge/facade-api.ts +0 -2
  167. package/src/cli/repositories/command-classifier.ts +0 -9
  168. package/src/cli/repositories/command-scope.ts +2 -2
  169. package/src/cli/repositories/locks.ts +20 -0
  170. package/src/cli/repositories/registry.ts +2 -1
  171. package/src/cli/repositories/safe-patch.ts +2 -12
  172. package/src/cli/repositories/structured-git.ts +39 -3
  173. package/src/cli/repository/inspector.ts +185 -343
  174. package/src/effects/process-runner.ts +17 -1
  175. package/src/runtime/context/generic-lsp-provider.ts +1 -1
  176. package/src/runtime/context/semantic-navigation-contract.ts +7 -0
  177. package/src/runtime/context/semantic-navigation.ts +1 -1
  178. package/src/runtime/control-plane/cleanup-artifact-retention.ts +4 -4
  179. package/src/runtime/control-plane/execution/work-delivery-service.ts +150 -31
  180. package/src/runtime/control-plane/execution/work-handle-authority.ts +12 -4
  181. package/src/runtime/control-plane/execution/work-handle-store.ts +53 -1
  182. package/src/runtime/control-plane/execution/work-operation-service.ts +20 -10
  183. package/src/runtime/control-plane/execution/work-preparation-service.ts +108 -4
  184. package/src/runtime/control-plane/execution/work-process-evidence.ts +2 -2
  185. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +28 -13
  186. package/src/runtime/control-plane/execution/work-validation-reconciler.ts +5 -1
  187. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +1 -1
  188. package/src/runtime/control-plane/facade/capability-registry.ts +2 -0
  189. package/src/runtime/control-plane/facade/work-continuation.ts +1 -1
  190. package/src/runtime/control-plane/generated-cache-retention.ts +114 -63
  191. package/src/runtime/control-plane/global-scheduler/maintenance.ts +20 -8
  192. package/src/runtime/control-plane/global-scheduler/reconciliation.ts +1 -11
  193. package/src/runtime/control-plane/governance/external-effects.ts +1 -1
  194. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +1 -0
  195. package/src/runtime/control-plane/runtime-cleanup.ts +12 -93
  196. package/src/runtime/evidence/sensitive-output.ts +22 -2
  197. package/src/runtime/execution/jobs/child-reference.ts +11 -0
  198. package/src/runtime/execution/jobs/receipt-recovery.ts +1 -11
  199. package/src/runtime/execution/process-runtime/command-facade.ts +3 -3
  200. package/src/runtime/execution/process-runtime/runtime.ts +20 -16
  201. package/src/runtime/execution/thin-harness/execution-router.ts +16 -16
  202. package/src/runtime/execution/thin-harness/fast-executor.ts +2 -2
  203. package/src/runtime/execution/thin-harness/search-worker.ts +2 -2
  204. package/src/runtime/execution/workers/executor.ts +1 -2
  205. package/src/runtime/maintenance/cleanup.ts +41 -5
  206. package/src/runtime/plugins/action-application.ts +12 -1
  207. package/src/runtime/plugins/app-store-connect-adapter.ts +252 -4
  208. package/src/runtime/plugins/browser-adapter.ts +381 -313
  209. package/src/runtime/plugins/browser-macos-bridge.ts +114 -112
  210. package/src/runtime/plugins/browser-manifest-surface.ts +2 -1
  211. package/src/runtime/plugins/browser-registration.ts +2 -0
  212. package/src/runtime/plugins/browser-runtime.ts +26 -35
  213. package/src/runtime/plugins/computer-chatgpt-browser-adapter-installer.ts +11 -2
  214. package/src/runtime/plugins/computer-registration.ts +76 -9
  215. package/src/runtime/plugins/github-adapter.ts +30 -3
  216. package/src/runtime/plugins/gmail-adapter.ts +166 -1
  217. package/src/runtime/plugins/google-shared.ts +10 -5
  218. package/src/runtime/plugins/ios/remote-xpc-hid.ts +70 -30
  219. package/src/runtime/plugins/ios-adapter.ts +45 -40
  220. package/src/runtime/plugins/ios-agent-device.ts +54 -4
  221. package/src/runtime/plugins/ios-device-ownership.ts +103 -0
  222. package/src/runtime/plugins/ios-physical-device.ts +497 -79
  223. package/src/runtime/plugins/local-system-adapter.ts +1 -99
  224. package/src/runtime/plugins/store.ts +80 -7
  225. package/src/runtime/plugins/types.ts +4 -0
  226. package/src/runtime/projections/git-status-sampler.ts +2 -19
  227. package/src/runtime/recovery/actions.ts +1 -1
  228. package/src/runtime/recovery/lifecycle-inventory.ts +1 -11
  229. package/src/runtime/recovery/probe.ts +2 -2
  230. package/src/runtime/release/release-coordinator.ts +20 -4
  231. package/src/runtime/root/controller-progression-composition.ts +67 -5
  232. package/src/runtime/root/package-connector-service.ts +123 -11
  233. package/src/runtime/root/package-runtime-release.ts +6 -18
  234. package/src/runtime/root/package-runtime-service.ts +7 -13
  235. package/src/runtime/root/release-execution-canary.ts +18 -5
  236. package/src/runtime/root/release-manifest.ts +0 -34
  237. package/src/runtime/root/release-materialize.ts +0 -78
  238. package/src/runtime/root/runtime.ts +1 -2
  239. package/src/runtime/root/scheduled-controller-composition.ts +2 -1
  240. package/src/runtime/root/service.ts +90 -11
  241. package/src/runtime/root/types.ts +0 -6
  242. package/src/runtime/root/workflow-supervisor-composition.ts +207 -19
  243. package/src/runtime/root/workflow-supervisor-runtime.ts +365 -10
  244. package/src/runtime/safe-tooling/google-credential-store.ts +1 -11
  245. package/src/runtime/safe-tooling/ios-development.ts +22 -8
  246. package/src/runtime/safe-tooling/job-summary.ts +1 -1
  247. package/src/runtime/safe-tooling/workspace-auth.ts +4 -1
  248. package/src/runtime/shared/atomic-text-file.ts +21 -0
  249. package/src/runtime/shared/json-files.ts +8 -3
  250. package/src/runtime/standalone-recovery/core.ts +189 -174
  251. package/src/runtime/standalone-recovery/entry.ts +62 -30
  252. package/src/runtime/standalone-recovery/operation-lock.ts +11 -1
  253. package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +1 -0
  254. package/src/runtime/workflow/schedules/engine.ts +36 -14
  255. package/src/runtime/workflow/schedules/pending-activation.ts +11 -4
  256. package/src/runtime/workflow/schedules/work-continuation.ts +51 -6
  257. package/supervisor/client.ts +31 -14
  258. package/supervisor/control-plane.ts +210 -115
  259. package/supervisor/forge-validators.ts +88 -21
  260. package/supervisor/native-browser-adapter.ts +393 -28
  261. package/supervisor/native-messaging/host.ts +21 -2
  262. package/supervisor/protocol.ts +74 -26
  263. package/supervisor/server.ts +16 -8
  264. package/supervisor/store.ts +476 -57
  265. package/supervisor/types.ts +19 -13
  266. package/SKILL.md +0 -427
  267. package/adapters/computer/chatgpt-target-router.ts +0 -103
  268. package/adapters/mcp/runtime-gateway/automation-receipt-adapter.ts +0 -87
  269. package/adapters/mcp/runtime-gateway/work-validation-reconciler.ts +0 -1
  270. package/adapters/mcp/toolset-selection.ts +0 -41
  271. package/agents/openai.yaml +0 -4
  272. package/assets/skill-hooks.json +0 -41
  273. package/assets/skill-version.json +0 -189
  274. package/assets/skills/claude-review/SKILL.md +0 -231
  275. package/assets/skills/codex-review/SKILL.md +0 -103
  276. package/assets/templates/helpers/check-skill-version.ts +0 -193
  277. package/scripts/check-skill-version.ts +0 -5
  278. package/scripts/ensure-codegraph.sh +0 -16
  279. package/scripts/run-skill-hook.ts +0 -244
  280. package/scripts/sync-codex-installed-copies.sh +0 -182
  281. package/src/cli/commands/tools.ts +0 -167
  282. package/src/cli/mcp/access-mode.ts +0 -2
  283. package/src/cli/mcp/access-tools.ts +0 -2
  284. package/src/cli/mcp/audit.ts +0 -2
  285. package/src/cli/mcp/auth.ts +0 -2
  286. package/src/cli/mcp/instructions.ts +0 -2
  287. package/src/cli/mcp/legacy-context.ts +0 -2
  288. package/src/cli/mcp/legacy-tool-service.ts +0 -2
  289. package/src/cli/mcp/multi-repository.ts +0 -2
  290. package/src/cli/mcp/oauth.ts +0 -2
  291. package/src/cli/mcp/openai-secure-tunnel.ts +0 -2
  292. package/src/cli/mcp/paths.ts +0 -2
  293. package/src/cli/mcp/policy.ts +0 -2
  294. package/src/cli/mcp/post-finalize-work-attribution.ts +0 -2
  295. package/src/cli/mcp/proxy-env.ts +0 -2
  296. package/src/cli/mcp/readiness-projection.ts +0 -2
  297. package/src/cli/mcp/redaction.ts +0 -2
  298. package/src/cli/mcp/repo.ts +0 -2
  299. package/src/cli/mcp/repository-tools.ts +0 -2
  300. package/src/cli/mcp/server.ts +0 -2
  301. package/src/cli/mcp/setup.ts +0 -2
  302. package/src/cli/mcp/tool-capability-cache.ts +0 -2
  303. package/src/cli/mcp/tool-contract.ts +0 -2
  304. package/src/cli/mcp/tools.ts +0 -2
  305. package/src/cli/mcp/toolset-names.ts +0 -2
  306. package/src/cli/mcp/toolset-selection.ts +0 -2
  307. package/src/cli/mcp/toolset.ts +0 -2
  308. package/src/cli/mcp/transports/http.ts +0 -2
  309. package/src/cli/mcp/transports/session-registry.ts +0 -2
  310. package/src/cli/mcp/transports/stdio.ts +0 -2
  311. package/src/cli/mcp/types.ts +0 -2
  312. package/src/cli/mcp/umbrella-tools.ts +0 -2
  313. package/src/cli/tools/codegraph.ts +0 -695
  314. package/src/core/adoption/helper-wrapper-plan.ts +0 -159
  315. package/src/runtime/context/codegraph-cache-boundary.ts +0 -255
  316. package/src/runtime/context/codegraph-read-provider.ts +0 -611
  317. package/src/runtime/context/codegraph-sidecar.cjs +0 -248
  318. package/src/runtime/control-plane/codegraph-cache-retention.ts +0 -164
  319. package/src/runtime/gateway/mcp/execution-tools.ts +0 -2
  320. package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +0 -2
  321. package/src/runtime/gateway/mcp/persisted-check-process.ts +0 -2
  322. package/src/runtime/gateway/mcp/process-tools.ts +0 -2
  323. package/src/runtime/gateway/mcp/router.ts +0 -2
  324. package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +0 -2
  325. package/src/runtime/gateway/mcp/runtime-tools.ts +0 -2
  326. package/src/runtime/gateway/mcp/work-validation-reconciler.ts +0 -2
  327. package/src/runtime/plugins/browser-provider-registry.ts +0 -2
  328. package/src/runtime/plugins/computer-chatgpt-macos-target.ts +0 -891
@@ -5,6 +5,7 @@ import { listControllerChecks } from '../../../src/cli/controller/check-runner';
5
5
  import { repositoryGitStatus } from '../../../src/cli/repositories/structured-git';
6
6
  import { getWorkContract, updateWorkContract, workSemanticView } from '../../../packages/kernel/work/api/index';
7
7
  import { ensureRepositoryWorkHandle } from '../../../src/runtime/control-plane/execution/work-handle-authority';
8
+ import { readWorkHandle } from '../../../src/runtime/control-plane/execution/work-handle-store';
8
9
  import { ensureManagedWorkspace } from '../../../src/runtime/execution/managed-workspace';
9
10
  import { ensureRepositoryProjectOnboarding } from '../../../src/runtime/control-plane/workspace/project-onboarding';
10
11
  import { buildFacadeResult } from '../../../src/runtime/control-plane/facade';
@@ -16,7 +17,7 @@ import { invalidFacadeOperation } from './status-inbox-adapter';
16
17
  import { normalizeRhWorkInputWireMigration } from './work-input-wire-migration';
17
18
  import { callRhWorkScheduleAdapter, isRhWorkScheduleOperation } from './scheduler-adapter';
18
19
  import { callRhWorkRequirementOperation, isRhWorkRequirementOperation } from './work-requirement-operations';
19
- import { callRhWorkSemanticOperation, semanticWorkId } from './work-semantic-operations';
20
+ import { buildWorkSemanticFacadeResult, callRhWorkSemanticOperation, semanticWorkId } from './work-semantic-operations';
20
21
  import { callRhWorkListProjection } from './work-list-projection';
21
22
  import {
22
23
  callRhWorkPlanCreateOperation,
@@ -27,7 +28,6 @@ import { callRhWorkWorkflowOperation } from './work-workflow-operations';
27
28
  import { callRhWorkLearningOperation } from './work-learning-operations';
28
29
  import { callRhWorkControllerOperation } from './work-controller-operations';
29
30
  import { runFacadeRepair } from './work-repair-adapter';
30
- import { isAutomationReceiptCompatibilityCall } from './automation-receipt-adapter';
31
31
  import { authenticatedFacadeControllerIdentity } from './controller-authority-adapter';
32
32
 
33
33
  export { runFacadeRepair };
@@ -79,12 +79,19 @@ async function callRepositoryBoundStart(
79
79
 
80
80
  try {
81
81
  const rawConstraints = contextRecord(args.constraints);
82
- // Placement is caller-owned. Legacy `auto` is a stable mechanical spelling
83
- // of the durable-Work isolated/frozen-base default; it never inspects dirty
84
- // paths, risk, task text, or other semantic context to choose topology.
85
- const requestedWorkspaceMode: 'current' | 'isolated' = rawConstraints.workspace_mode === 'isolated' || rawConstraints.workspace_mode === 'auto'
86
- ? 'isolated'
87
- : 'current';
82
+ // Placement is caller-owned. Omitted placement and legacy `auto` are the
83
+ // stable mechanical spelling of the durable-Work isolated/frozen-base default;
84
+ // only explicit `current` may reuse the selected canonical checkout.
85
+ const requestedWorkspaceMode: 'current' | 'isolated' = rawConstraints.workspace_mode === 'current'
86
+ ? 'current'
87
+ : 'isolated';
88
+ const existingHandle = readWorkHandle(ctx.controllerHome, repository.repoId, workId);
89
+ if (existingHandle) {
90
+ const existingWorkspaceMode = existingHandle.managedWorktree ? 'isolated' : 'current';
91
+ if (existingWorkspaceMode !== requestedWorkspaceMode) {
92
+ throw new Error(`WORK_REPOSITORY_ADMISSION_PLACEMENT_CONFLICT: ${workId}; existing=${existingWorkspaceMode}; requested=${requestedWorkspaceMode}`);
93
+ }
94
+ }
88
95
  const sourceStatus = repositoryGitStatus(repository);
89
96
  const requestedSourceRevision = typeof args.source_revision === 'string' ? args.source_revision.trim() : '';
90
97
  if (requestedSourceRevision && sourceStatus.head && requestedWorkspaceMode !== 'isolated' && requestedSourceRevision !== sourceStatus.head) {
@@ -137,7 +144,7 @@ async function callRepositoryBoundStart(
137
144
  repository,
138
145
  sourceRevision: baseRevision,
139
146
  });
140
- return result(buildFacadeResult({
147
+ return result(buildWorkSemanticFacadeResult({
141
148
  summary: `Work ${workId} admitted to repository execution on checkout ${checkoutId}.`,
142
149
  data: {
143
150
  work: workSemanticView(contract),
@@ -257,13 +264,6 @@ export async function callWorkAdapter(
257
264
  const operation = wireMigration.operation;
258
265
  if (!isRhWorkAcceptedOperation(operation)) return invalidFacadeOperation('rh_work', operation);
259
266
 
260
- if (operation === 'repair' && isAutomationReceiptCompatibilityCall(args)) {
261
- return result(buildFacadeResult({
262
- summary: 'Workflow Supervisor automation receipt accepted for canonical persistence.',
263
- data: { automationReceiptCompatibility: true },
264
- }) as unknown as Record<string, unknown>);
265
- }
266
-
267
267
  if (isRhWorkRequirementOperation(operation) && operation !== 'requirement_promote_candidate') {
268
268
  const requirement = await callRhWorkRequirementOperation(ctx, undefined, operation, args);
269
269
  if (requirement) return requirement;
@@ -1,5 +1,4 @@
1
1
  import { isDeepStrictEqual } from 'node:util';
2
- import { AUTOMATION_RECEIPT_CAPABILITY_PREFIX } from './automation-receipt-adapter';
3
2
 
4
3
  export type RhWorkInputWireMigrationResult =
5
4
  | {
@@ -220,22 +219,6 @@ export function normalizeRhWorkInputWireMigration(input: Record<string, unknown>
220
219
  return translateFrozenSemanticV1(args, parsed.value);
221
220
  }
222
221
 
223
- if (capabilityId.startsWith(AUTOMATION_RECEIPT_CAPABILITY_PREFIX)) {
224
- // Frozen clients attach ordinary repository context and a reason. These are
225
- // transport annotations, never receipt/task/effect authority. Strip them;
226
- // the canonical Supervisor derives all causal identity from its own journal.
227
- const allowed = new Set(['operation', 'capability_id', 'repo_id', 'checkout_id', 'reason']);
228
- const unsupported = unsupportedInputField(args, allowed);
229
- if (unsupported) return failure('FROZEN_MCP_AUTOMATION_RECEIPT_FIELD_UNSUPPORTED', { field: unsupported });
230
- if (requestedOperation !== 'repair') return failure('FROZEN_MCP_AUTOMATION_RECEIPT_OPERATION_INVALID', { operation: requestedOperation });
231
- for (const field of ['repo_id', 'checkout_id', 'reason']) {
232
- if (args[field] !== undefined && (typeof args[field] !== 'string' || (args[field] as string).length > 2_000)) {
233
- return failure('FROZEN_MCP_AUTOMATION_RECEIPT_FIELD_INVALID', { field });
234
- }
235
- }
236
- return { ok: true, args: { operation: 'repair', capability_id: capabilityId }, operation: 'repair' };
237
- }
238
-
239
222
  if (capabilityId.includes(':')) {
240
223
  return failure('FROZEN_MCP_LIFECYCLE_REMOVED: only bounded semantic.v1 and current-conversation enrollment carriers remain supported.', {
241
224
  carrier: capabilityId.slice(0, capabilityId.indexOf(':')),
@@ -12,7 +12,7 @@ import {
12
12
  semanticWorkState,
13
13
  type WorkContractStoreOptions,
14
14
  } from '../../../packages/kernel/work/api/index';
15
- import { buildFacadeResult } from '../../../src/runtime/control-plane/facade';
15
+ import { buildFacadeResult, type BuildFacadeResultOptions } from '../../../src/runtime/control-plane/facade';
16
16
  import { getPlanContract, currentPlanSemanticRevision, getPlanSemanticRevisionRecord, planSemanticView } from '../../../src/runtime/control-plane/facade/plan-contract-store';
17
17
  import { readRequirement, currentRequirementSemanticRevision, getRequirementRevisionRecord, requirementSemanticView } from '../../../src/runtime/control-plane/persistence/requirement-store';
18
18
  import { buildWorkContinuationSnapshot } from '../../../src/runtime/control-plane/facade/work-continuation';
@@ -21,8 +21,61 @@ import { projectWorkExecutionEvidence } from './work-detail-projection';
21
21
  import { readWorkHandle } from '../../../src/runtime/control-plane/execution/work-handle-store';
22
22
  import { reconcileSingleTerminalWorkCleanup } from '../../../src/runtime/control-plane/execution/work-terminal-cleanup';
23
23
 
24
+ import { existsSync } from 'node:fs';
25
+ import { getWorkflowSupervisorTask, stopWorkflowSupervisorTask } from '../../../supervisor/client';
26
+ import { workflowSupervisorSocketPath } from '../../../supervisor/paths';
27
+
28
+ async function stopTerminalWorkSupervisor(
29
+ options: WorkContractStoreOptions,
30
+ workId: string,
31
+ state: 'completed' | 'cancelled',
32
+ ): Promise<{ status: 'stopped' | 'already_terminal' | 'not_enrolled' | 'pending_reconcile'; reason?: string }> {
33
+ const controllerHome = options.controllerHome;
34
+ const repoId = options.repoId?.trim();
35
+ if (!controllerHome || !repoId || !existsSync(workflowSupervisorSocketPath(controllerHome))) {
36
+ return { status: 'pending_reconcile', reason: 'Supervisor socket unavailable; native consumer will reconcile terminal Work on restart.' };
37
+ }
38
+ const taskId = `forge:${repoId}:work:${workId}`;
39
+ try {
40
+ const task = await getWorkflowSupervisorTask(controllerHome, taskId);
41
+ if (!task) return { status: 'not_enrolled' };
42
+ // Fail closed: an unrelated Requirement/standalone Goal must never be
43
+ // stopped by a lower-layer Work transition.
44
+ if (task.taskId !== taskId || task.completionContract?.work_id !== workId
45
+ || task.completionContract?.repo_id !== repoId
46
+ || task.continuationPolicy.kind === 'standalone_supervisor') {
47
+ return { status: 'pending_reconcile', reason: 'Supervisor task contract is not exact Work-owned.' };
48
+ }
49
+ const stopped = await stopWorkflowSupervisorTask(controllerHome, taskId, `Work ${workId} changed to ${state}; its exact Work-owned automatic continuation is closed.`);
50
+ return { status: stopped.deduplicated ? 'already_terminal' : 'stopped' };
51
+ } catch (error) {
52
+ const reason = error instanceof Error ? error.message : String(error);
53
+ const code = reason.split(':', 1)[0]?.trim();
54
+ if (code === 'WORKFLOW_SUPERVISOR_TASK_UNKNOWN') return { status: 'not_enrolled' };
55
+ if (code === 'WORKFLOW_SUPERVISOR_TASK_TERMINAL') return { status: 'already_terminal' };
56
+ return { status: 'pending_reconcile', reason };
57
+ }
58
+ }
59
+
24
60
  const RH_WORK_SEMANTIC_OPERATIONS = new Set(['start', 'get', 'revise', 'complete']);
25
61
 
62
+ type WorkSemanticFacadeData = Record<string, unknown> & {
63
+ work?: ReturnType<typeof workSemanticView>;
64
+ currentWork?: ReturnType<typeof workSemanticView>;
65
+ revisionHistory?: ReturnType<typeof listWorkSemanticRevisionRecords>;
66
+ };
67
+
68
+ export function buildWorkSemanticFacadeResult(options: BuildFacadeResultOptions<WorkSemanticFacadeData>) {
69
+ const facade = buildFacadeResult(options);
70
+ // These authored projections already have domain limits. Generic diagnostic
71
+ // clipping corrupts their read/revise round trip (100 refs become 50, and a
72
+ // valid objective becomes an ellipsis). Keep execution diagnostics bounded.
73
+ if (options.data.work) facade.data.work = options.data.work;
74
+ if (options.data.currentWork) facade.data.currentWork = options.data.currentWork;
75
+ if (options.data.revisionHistory) facade.data.revisionHistory = options.data.revisionHistory;
76
+ return facade;
77
+ }
78
+
26
79
  /** Resolve semantic version references against existing canonical heads/history. */
27
80
  function workBasis(store: WorkContractStoreOptions, x: { requirementId?: string; requirementRevision?: number; planId?: string; planRevision?: number }) {
28
81
  const plan = x.planId ? getPlanContract(store, x.planId) : undefined;
@@ -118,18 +171,18 @@ export async function callRhWorkSemanticOperation(
118
171
  const workId = operation === 'start' ? semanticWorkId(store, args) : String(args.work_id ?? '').trim();
119
172
  if (operation === 'start') {
120
173
  const objective = String(args.objective ?? '').trim();
121
- if (!objective) return result(buildFacadeResult({
174
+ if (!objective) return result(buildWorkSemanticFacadeResult({
122
175
  status: 'blocked', summary: 'WORK_OBJECTIVE_REQUIRED', data: { workId },
123
176
  }) as unknown as Record<string, unknown>, true);
124
177
  const requestId = typeof args.request_id === 'string' ? args.request_id.trim() : '';
125
178
  const existing = getWorkContract(store, workId);
126
179
  if (existing) {
127
- if (!semanticCreateMatches(existing, args, requestId)) return result(buildFacadeResult({
180
+ if (!semanticCreateMatches(existing, args, requestId)) return result(buildWorkSemanticFacadeResult({
128
181
  status: 'blocked',
129
182
  summary: `WORK_SEMANTIC_CREATE_CONFLICT: ${workId}`,
130
183
  data: { workId, currentWork: workSemanticView(existing) },
131
184
  }) as unknown as Record<string, unknown>, true);
132
- return result(buildFacadeResult({
185
+ return result(buildWorkSemanticFacadeResult({
133
186
  summary: `Work ${workId} already exists; semantic create was deduplicated.`,
134
187
  data: { work: workSemanticView(existing), deduplicated: true },
135
188
  }) as unknown as Record<string, unknown>);
@@ -150,17 +203,17 @@ export async function callRhWorkSemanticOperation(
150
203
  ...(Array.isArray(args.depends_on_work_ids) ? { dependsOnWorkIds: args.depends_on_work_ids.map(String) } : {}),
151
204
  ...(requestId ? { requestId } : {}),
152
205
  });
153
- return result(buildFacadeResult({
206
+ return result(buildWorkSemanticFacadeResult({
154
207
  summary: `Work ${workId} created as semantic context.`,
155
208
  data: { work: workSemanticView(created), deduplicated: false },
156
209
  }) as unknown as Record<string, unknown>);
157
210
  } catch (error) {
158
211
  const raced = getWorkContract(store, workId);
159
- if (raced && semanticCreateMatches(raced, args, requestId)) return result(buildFacadeResult({
212
+ if (raced && semanticCreateMatches(raced, args, requestId)) return result(buildWorkSemanticFacadeResult({
160
213
  summary: `Work ${workId} already exists; semantic create was deduplicated.`,
161
214
  data: { work: workSemanticView(raced), deduplicated: true },
162
215
  }) as unknown as Record<string, unknown>);
163
- return result(buildFacadeResult({
216
+ return result(buildWorkSemanticFacadeResult({
164
217
  status: 'blocked',
165
218
  summary: error instanceof Error ? error.message : String(error),
166
219
  data: { workId },
@@ -169,7 +222,7 @@ export async function callRhWorkSemanticOperation(
169
222
  }
170
223
  if (operation === 'get') {
171
224
  const work = workId ? getWorkContract(store, workId) : undefined;
172
- if (!work) return result(buildFacadeResult({
225
+ if (!work) return result(buildWorkSemanticFacadeResult({
173
226
  status: 'not_found', summary: `Work ${workId || '(missing)'} not found.`, data: { workId },
174
227
  }) as unknown as Record<string, unknown>, true);
175
228
  const semantic = workSemanticView(work);
@@ -180,7 +233,7 @@ export async function callRhWorkSemanticOperation(
180
233
  listWorkSemanticRevisionRecords(store, undefined, 200),
181
234
  semantic.workId,
182
235
  ) : undefined;
183
- return result(buildFacadeResult({
236
+ return result(buildWorkSemanticFacadeResult({
184
237
  summary: `Work ${semantic.workId} retrieved at semantic revision ${semantic.revision}.`,
185
238
  data: {
186
239
  work: semantic,
@@ -222,9 +275,12 @@ export async function callRhWorkSemanticOperation(
222
275
  ...(Array.isArray(args.work_result_refs) ? { resultRefs: args.work_result_refs.map(String) } : {}),
223
276
  });
224
277
  const semantic = workSemanticView(revised);
278
+ const supervisorClosure = semantic.state !== 'open'
279
+ ? await stopTerminalWorkSupervisor(store, semantic.workId, semantic.state)
280
+ : undefined;
225
281
  let resourceReconciliation: Awaited<ReturnType<typeof reconcileSingleTerminalWorkCleanup>> | undefined;
226
282
  if (
227
- operation === 'complete'
283
+ semantic.state !== 'open'
228
284
  && store.controllerHome
229
285
  && revised.repoId?.trim()
230
286
  && readWorkHandle(store.controllerHome, revised.repoId, revised.workId)
@@ -243,19 +299,20 @@ export async function callRhWorkSemanticOperation(
243
299
  };
244
300
  }
245
301
  }
246
- return result(buildFacadeResult({
302
+ return result(buildWorkSemanticFacadeResult({
247
303
  summary: `Work ${semantic.workId} revised atomically to semantic revision ${semantic.revision}.`,
248
304
  data: {
249
305
  work: semantic,
250
306
  expectedRevision,
251
307
  semanticRevision: semantic.revision,
252
308
  versionBinding: versionBinding(store, revised, false),
309
+ ...(supervisorClosure ? { supervisorClosure } : {}),
253
310
  ...(resourceReconciliation ? { resourceReconciliation } : {}),
254
311
  },
255
312
  }) as unknown as Record<string, unknown>);
256
313
  } catch (error) {
257
314
  const current = workId ? getWorkContract(store, workId) : undefined;
258
- return result(buildFacadeResult({
315
+ return result(buildWorkSemanticFacadeResult({
259
316
  status: 'blocked', summary: error instanceof Error ? error.message : String(error),
260
317
  data: { workId, expectedRevision, ...(current ? { currentWork: workSemanticView(current) } : {}) },
261
318
  }) as unknown as Record<string, unknown>, true);
@@ -5,6 +5,7 @@ import {
5
5
  getWorkflowSupervisorTask,
6
6
  getWorkflowSupervisorTaskStall,
7
7
  listWorkflowSupervisorTasks,
8
+ listWorkflowSupervisorTerminalTasks,
8
9
  migrateWorkflowSupervisorConversation,
9
10
  recoverWorkflowSupervisorTask,
10
11
  registerWorkflowSupervisorTask,
@@ -13,6 +14,7 @@ import {
13
14
  stopWorkflowSupervisorTask,
14
15
  } from '../../../supervisor/client';
15
16
  import { resolveWorkflowSupervisorForgeHome } from '../../../supervisor/paths';
17
+ import { workflowSupervisorCompletionContractSha256 } from '../../../supervisor/store';
16
18
  import type { MultiRepositoryMcpToolContext } from '../multi-repository';
17
19
  import { result } from './result-adapter';
18
20
 
@@ -40,6 +42,10 @@ export async function callWorkflowSupervisorAdapter(
40
42
  const requestId = textArg(args, 'request_id');
41
43
  if (!objective) throw new Error('WORKFLOW_SUPERVISOR_OBJECTIVE_REQUIRED');
42
44
  if (!requestId) throw new Error('WORKFLOW_SUPERVISOR_REQUEST_ID_REQUIRED');
45
+ const workId = textArg(args, 'work_id');
46
+ const requirementId = textArg(args, 'requirement_id');
47
+ if (workId && requirementId) throw new Error('WORKFLOW_SUPERVISOR_SEMANTIC_BINDING_AMBIGUOUS');
48
+ if ((workId || requirementId) && !repoId) throw new Error('WORKFLOW_SUPERVISOR_SEMANTIC_BINDING_REPO_REQUIRED');
43
49
  const id = standaloneTaskId(repoId, requestId);
44
50
  const task = await registerWorkflowSupervisorTask(forgeHome, {
45
51
  taskId: id,
@@ -49,6 +55,8 @@ export async function callWorkflowSupervisorAdapter(
49
55
  completionContract: {
50
56
  kind: 'model_semantic_completion',
51
57
  ...(repoId ? { repo_id: repoId, controller_home: ctx.controllerHome } : {}),
58
+ ...(workId ? { work_id: workId } : {}),
59
+ ...(requirementId ? { requirement_id: requirementId } : {}),
52
60
  },
53
61
  continuationPolicy: { kind: 'standalone_supervisor', bootstrap: true, ...(repoId ? { repo_id: repoId } : {}) },
54
62
  userBlockerPolicy: { kind: 'model_semantic_user_blocker' },
@@ -58,6 +66,10 @@ export async function callWorkflowSupervisorAdapter(
58
66
  }
59
67
 
60
68
  if (operation === 'list') {
69
+ if (args.terminal_only === true) {
70
+ const terminalTasks = await listWorkflowSupervisorTerminalTasks(forgeHome);
71
+ return result({ terminalTasks, count: terminalTasks.length, terminalOnly: true, summary: `${terminalTasks.length} canonically terminal Supervisor task(s) in retained history; conversations are not archived or deleted.` });
72
+ }
61
73
  const activeOnly = args.active_only !== false;
62
74
  const tasks = await listWorkflowSupervisorTasks(forgeHome, activeOnly);
63
75
  return result({ tasks, count: tasks.length, activeOnly, summary: `${tasks.length} Supervisor task(s) listed.` });
@@ -67,19 +79,31 @@ export async function callWorkflowSupervisorAdapter(
67
79
  const id = textArg(args, 'task_id');
68
80
  const objective = textArg(args, 'objective');
69
81
  const expectedObjectiveSha256 = textArg(args, 'expected_objective_sha256');
82
+ const expectedCompletionContractSha256 = textArg(args, 'expected_completion_contract_sha256');
83
+ const workId = textArg(args, 'work_id');
84
+ const requirementId = textArg(args, 'requirement_id');
70
85
  const requestId = textArg(args, 'request_id');
71
86
  if (!id) throw new Error('WORKFLOW_SUPERVISOR_TASK_ID_REQUIRED');
72
87
  if (!objective) throw new Error('WORKFLOW_SUPERVISOR_OBJECTIVE_REQUIRED');
73
88
  if (!expectedObjectiveSha256) throw new Error('WORKFLOW_SUPERVISOR_OBJECTIVE_REVISION_EXPECTED_SHA_REQUIRED');
74
89
  if (!requestId) throw new Error('WORKFLOW_SUPERVISOR_REQUEST_ID_REQUIRED');
90
+ if (workId && requirementId) throw new Error('WORKFLOW_SUPERVISOR_SEMANTIC_BINDING_TARGET_INVALID');
91
+ if ((workId || requirementId) && !expectedCompletionContractSha256) throw new Error('WORKFLOW_SUPERVISOR_COMPLETION_CONTRACT_REVISION_EXPECTED_SHA_REQUIRED');
92
+ if (!(workId || requirementId) && expectedCompletionContractSha256) throw new Error('WORKFLOW_SUPERVISOR_COMPLETION_CONTRACT_REVISION_TARGET_REQUIRED');
75
93
  const revised = await reviseWorkflowSupervisorTaskObjective(forgeHome, {
76
94
  taskId: id,
77
95
  objective,
78
96
  expectedObjectiveSha256,
79
97
  requestId,
98
+ ...(workId ? { workId } : {}),
99
+ ...(requirementId ? { requirementId } : {}),
100
+ ...(expectedCompletionContractSha256 ? { expectedCompletionContractSha256 } : {}),
80
101
  authorizedBy: textArg(args, 'authorized_by') || 'operator',
81
102
  });
82
- return result({ ...revised, summary: `Supervisor task ${id} objective ${revised.changed ? 'revised' : 'confirmed'} in place.` });
103
+ const bindingSummary = workId || requirementId
104
+ ? `; semantic completion binding ${revised.semanticBindingChanged ? 'revised' : 'confirmed'}`
105
+ : '';
106
+ return result({ ...revised, summary: `Supervisor task ${id} objective ${revised.changed ? 'revised' : 'confirmed'} in place${bindingSummary}.` });
83
107
  }
84
108
 
85
109
  if (operation === 'stop') {
@@ -138,7 +162,7 @@ export async function callWorkflowSupervisorAdapter(
138
162
  // retry/resume budget used to make the task silently leave the delivery
139
163
  // queue. The stall state names the exact operator action that can move it.
140
164
  const stall = await getWorkflowSupervisorTaskStall(forgeHome, id).catch(() => undefined);
141
- return result({ task, ...(stall ? { stall } : {}), summary: `Supervisor task ${id} retrieved${stall ? ` (${stall.state})` : ''}.` });
165
+ return result({ task, completionContractSha256: workflowSupervisorCompletionContractSha256(task.completionContract), ...(stall ? { stall } : {}), summary: `Supervisor task ${id} retrieved${stall ? ` (${stall.state})` : ''}; canonical completion-contract CAS fingerprint included.` });
142
166
  }
143
167
 
144
168
  if (operation === 'proof') {
@@ -16,7 +16,7 @@ import { callAccessTool } from './tool-mapping/access-tools';
16
16
  import { callRepositoryToolWithPostFinalizeAttribution } from './tool-mapping/post-finalize-work-attribution';
17
17
  import { callRuntimeTool } from './runtime-gateway/runtime-tools';
18
18
  import { callExecutionTool } from './runtime-gateway/execution-tools';
19
- import { callProcessTool } from './runtime-gateway/process-tools';
19
+ import { callProcessTool, executeAuthorizedHostCommand } from './runtime-gateway/process-tools';
20
20
  import { injectDurableCommandFields, isGatewayIsolatedTool, routeDurableMcpCall } from './runtime-gateway/router';
21
21
  import { controllerExposureSnapshot, isControllerToolExposed } from './toolset';
22
22
  import { settleCognitionAfterTool } from './runtime-gateway/cognition-settlement';
@@ -507,7 +507,7 @@ export function sameCanonicalRuntimeProxyIdentity(
507
507
  }
508
508
 
509
509
  export function canonicalRuntimeToolCallIsReplaySafe(name: string, args: Record<string, unknown>): boolean {
510
- if (name !== 'repository_command_execute') return false;
510
+ if (name !== 'execute_command') return false;
511
511
  const workId = typeof args.work_id === 'string' ? args.work_id.trim() : '';
512
512
  const requestId = typeof args.request_id === 'string' ? args.request_id.trim() : '';
513
513
  return Boolean(workId && requestId);
@@ -1029,7 +1029,7 @@ export function createForgeMcpServerFromContext(
1029
1029
  if (isMultiRepositoryContext(ctx)) {
1030
1030
  const rpcId = handlerContext.mcpReq.id;
1031
1031
  return traceControllerMcpRequest(ctx, name, args, typeof rpcId === 'string' || typeof rpcId === 'number' ? rpcId : undefined, async (requestId, _traceId, phaseTimings) => {
1032
- // The public Gateway only exposes its stable facade schema. It may
1032
+ // The public Gateway serves one complete canonical tool schema. It may
1033
1033
  // proxy execution, but it never discovers one Runtime schema and
1034
1034
  // validates calls against another source checkout.
1035
1035
  if (!getRuntimeWriteClaim() && !runtimeSchema && !canonicalRuntimeSchemaMatchesGateway(ctx)) {
@@ -1060,6 +1060,17 @@ export function createForgeMcpServerFromContext(
1060
1060
  if (runtimeProxy && observeRuntimeStatus(ctx.controllerHome).ready) return runtimeProxy.callTool(ctx, name, forwardedArgs, phaseTimings);
1061
1061
  }
1062
1062
  const executeLocalTool = async (): Promise<CallToolResult> => {
1063
+ if (name === 'execute_command' && args.scope === 'host') {
1064
+ if (args.dry_run === true) {
1065
+ return { content: [{ type: 'text', text: 'HOST_COMMAND_PREVIEW_UNSUPPORTED: host command preview requires a separate explicit grant-aware facility' }], structuredContent: { error: { code: 'HOST_COMMAND_PREVIEW_UNSUPPORTED' } }, isError: true };
1066
+ }
1067
+ if (args.repo_id !== undefined || args.checkout_id !== undefined || args.workspace_root !== undefined) {
1068
+ return { content: [{ type: 'text', text: 'COMMAND_SCOPE_CONFLICT: host execution cannot claim repository or workspace targeting' }], structuredContent: { error: { code: 'COMMAND_SCOPE_CONFLICT', message: 'Host execution cannot claim repository or workspace targeting' } }, isError: true };
1069
+ }
1070
+ // One exposed command, two existing authorization targets. The host
1071
+ // lane checks its canonical ForgeInstance process:exec Grant itself.
1072
+ return executeAuthorizedHostCommand(ctx, args);
1073
+ }
1063
1074
  const accessResult = callAccessTool(ctx, name, args);
1064
1075
  if (accessResult) return accessResult;
1065
1076
  const executionResult = await callExecutionTool(ctx, name, args);
@@ -1076,9 +1087,19 @@ export function createForgeMcpServerFromContext(
1076
1087
  if (durableResult) return durableResult;
1077
1088
  const repositoryResult = await callRepositoryToolWithPostFinalizeAttribution(ctx.controllerHome, name, args, ctx);
1078
1089
  if (repositoryResult) return repositoryResult;
1090
+ if (name === 'controller_capabilities') {
1091
+ // Legacy read-only diagnostics consume the authoritative tools/list
1092
+ // snapshot; legacy handlers must not import Runtime registries.
1093
+ return await callMultiRepositoryTool({
1094
+ ...ctx,
1095
+ publishedToolNames: controllerExposureSnapshot(ctx).actualToolNames,
1096
+ }, name, args);
1097
+ }
1079
1098
  return await callMultiRepositoryTool(ctx, name, args);
1080
1099
  };
1081
1100
  const localResult = await executeLocalTool();
1101
+ // MCP calls are intermediate. Only the provider-observed final assistant
1102
+ // response can close a Supervisor turn.
1082
1103
  return settleCognitionAfterTool(ctx, name, args, localResult) ?? localResult;
1083
1104
  });
1084
1105
  }
@@ -24,8 +24,7 @@ import {
24
24
  MAX_AGENT_TIMEOUT_MS,
25
25
  } from "../../src/cli/controller/runtime-config";
26
26
  import { ensureControllerHome, ensureRepoPreferredControllerHome } from "../../src/cli/repositories/controller-home";
27
- import { accessModeForLegacyToolset } from "./access-mode";
28
- import { migrateControllerToolsetConfig } from "./toolset-selection";
27
+ import { configuredControllerAccessMode } from './access-mode';
29
28
  import { ensureForgeInstanceIdentity, normalizeConfiguredForgeInstanceId, readForgeInstanceIdentity } from "../../packages/kernel/identity/api/index";
30
29
  import { discoverExecutable } from "../../src/runtime/platform/executable-discovery";
31
30
 
@@ -383,8 +382,6 @@ export function runMcpSetupChatgpt(opts: {
383
382
  const oauth = ensureMcpControllerHomeOAuthPassphrase(controllerHome);
384
383
  if (token.changed) changed.push(token.path);
385
384
  if (oauth.changed) changed.push(oauth.path);
386
- const migratedToolset = migrateControllerToolsetConfig(existingConfig);
387
- const toolset = migratedToolset.toolset;
388
385
  const config = {
389
386
  version: Math.max(existingConfig?.version ?? 1, 3),
390
387
  identity: { forgeInstanceId: forgeInstance.instanceId },
@@ -408,10 +405,7 @@ export function runMcpSetupChatgpt(opts: {
408
405
  localEndpoint: `http://127.0.0.1:${connectorPort}/mcp`,
409
406
  },
410
407
  profile: existingConfig?.profile ?? "controller",
411
- toolset,
412
- toolsetExplicit: migratedToolset.toolsetExplicit,
413
- accessMode: existingConfig?.accessMode
414
- ?? accessModeForLegacyToolset(existingConfig?.toolset ?? toolset),
408
+ accessMode: configuredControllerAccessMode(existingConfig),
415
409
  accessModeUpdatedAt: existingConfig?.accessModeUpdatedAt,
416
410
  accessModeRevision: existingConfig?.accessModeRevision ?? 0,
417
411
  localController: opts.userLevel && !existingConfig?.repo
@@ -470,7 +464,7 @@ export function runMcpSetupChatgpt(opts: {
470
464
  `[forge mcp] Forge instance: ${forgeInstance.instanceId}`,
471
465
  opts.userLevel ? `[forge mcp] Scope: user (${controllerHome})` : `[forge mcp] Repo: ${repoRoot}`,
472
466
  "[forge mcp] Profile: controller",
473
- `[forge mcp] Toolset: ${config.toolset}`,
467
+ '[forge mcp] Tools: complete Forge capability registry',
474
468
  `[forge mcp] ChatGPT MCP server name: ${serverName}`,
475
469
  `[forge mcp] Internal Runtime endpoint: http://${host}:${port}/mcp`,
476
470
  `[forge mcp] ChatGPT local OAuth endpoint: http://127.0.0.1:${connectorPort}/mcp`,
@@ -686,7 +680,7 @@ export function runMcpDoctor(opts: {
686
680
  : "not_adopted",
687
681
  repo: repoRoot,
688
682
  mcp: {
689
- toolset: migrateControllerToolsetConfig(localConfig).toolset,
683
+ toolset: 'full',
690
684
  localConfig: existsSync(mcpControllerHomeLocalConfigPath(controllerHome)) || existsSync(
691
685
  join(repoRoot, ".forge", "mcp.local.json"),
692
686
  ),
@@ -167,8 +167,6 @@ function accessStatePayload(
167
167
  effective = resolveControllerAccessState({
168
168
  controllerHome: ctx.controllerHome,
169
169
  repoRoot: ctx.explicitRepository?.canonicalRoot,
170
- toolsetOverride: ctx.toolset,
171
- toolsetLocked: ctx.toolsetLocked,
172
170
  }),
173
171
  ) {
174
172
  const repositoryPolicy = readRepositoryAccessPolicy(ctx.controllerHome, repository.repoId);
@@ -206,8 +204,6 @@ function previewPayload(
206
204
  const currentEffective = resolveControllerAccessState({
207
205
  controllerHome: ctx.controllerHome,
208
206
  repoRoot: ctx.explicitRepository?.canonicalRoot,
209
- toolsetOverride: ctx.toolset,
210
- toolsetLocked: ctx.toolsetLocked,
211
207
  });
212
208
  const currentPolicy = readRepositoryAccessPolicy(ctx.controllerHome, repository.repoId);
213
209
  const currentGroups = accessToolGroups(currentEffective.effectiveAccessMode);
@@ -280,8 +276,6 @@ export function callAccessTool(
280
276
  const effective = resolveControllerAccessState({
281
277
  controllerHome: ctx.controllerHome,
282
278
  repoRoot: ctx.explicitRepository?.canonicalRoot,
283
- toolsetOverride: ctx.toolset,
284
- toolsetLocked: ctx.toolsetLocked,
285
279
  });
286
280
  return result({
287
281
  ...accessStatePayload(ctx, repository, configured, effective),