@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
@@ -1,7 +1,7 @@
1
1
  import { existsSync, readFileSync } from 'fs';
2
2
  import type { McpToolDefinition, CallToolResult } from '../../../packages/protocols/mcp/tool-contract';
3
3
  import type { MultiRepositoryMcpToolContext } from '../multi-repository';
4
- import { repositoryGitStatus, repositoryGitDiff } from '../../../src/cli/repositories/structured-git';
4
+ import { repositoryGitWorkspaceChanges } from '../../../src/cli/repositories/structured-git';
5
5
  import { listControllerChecks } from '../../../src/cli/controller/check-runner';
6
6
  import { buildWorkContinuationSnapshot } from '../../../src/runtime/control-plane/facade/work-continuation';
7
7
  import { currentControllerInstanceId, startExecutionSession, type ExecutionSessionContext } from '../../../src/runtime/control-plane/execution/session-store';
@@ -12,7 +12,7 @@ import { resumeExecutionJobAfterApproval } from '../../../src/runtime/execution/
12
12
  import { recordMcpTiming, type McpTimingTrace } from '../../../src/runtime/diagnostics/mcp-timing';
13
13
  import { compactHandle, contractFor, identityFor, makeBoundedWorkResult, principalFor, requireSession, workForSession } from '../../../src/runtime/control-plane/execution/work-execution-support';
14
14
  import { bindSessionRepository, prepareWork } from '../../../src/runtime/control-plane/execution/work-preparation-service';
15
- import { executeWork, validateWork } from '../../../src/runtime/control-plane/execution/work-operation-service';
15
+ import { validateWork } from '../../../src/runtime/control-plane/execution/work-operation-service';
16
16
 
17
17
  export { selectDefaultWorkValidationChecks } from '../../../src/runtime/control-plane/execution/work-operation-service';
18
18
 
@@ -33,13 +33,9 @@ export const executionToolDefinitions: McpToolDefinition[] = [
33
33
  isolation: { type: 'string', enum: ['reuse', 'new_worktree', 'auto'] }, base_ref: { type: 'string' }, needs_dependencies: { type: 'boolean' },
34
34
  expected_previous_head: { type: 'string', description: 'Explicit prior WorkHandle HEAD required for audited successor adoption of an existing work_id.' },
35
35
  adopt_candidate_head: { type: 'string', description: 'Explicit current successor commit to adopt after exact identity, ownership, cleanliness, and ancestry validation.' },
36
+ relocate_to_new_worktree: { type: 'boolean', description: 'Move this existing Work identity to its own managed worktree, with exact previous/candidate HEADs and base_ref. WorkHandle and WorkContract placement commit atomically; the source checkout is not mutated.' },
36
37
  }, [], false),
37
38
  definition('work_inspect', 'Collect bounded Git, WorkContract, changed-path, check, and readiness evidence through one work handle.', { session_id: sessionId, repo_id: repoId, work_id: workId, detail: { type: 'string', enum: ['summary', 'detail'] } }, ['work_id'], true),
38
- definition('work_execute', 'Execute approved, repository-scoped commands against a validated work handle while preserving the existing command policy and audit path.', {
39
- session_id: sessionId, controller_id: { type: 'string', description: 'Controller identity that holds the Work lease. Defaults to the authenticated principal.' }, repo_id: repoId, work_id: workId,
40
- command: { anyOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' }, minItems: 1 }] }, approval_token: { type: 'string' }, cwd: { type: 'string' }, timeout_ms: { type: 'number' }, max_output_bytes: { type: 'number' },
41
- commands: { type: 'array', items: { type: 'object' } }, approval_request_id: { type: 'string' },
42
- }, ['work_id'], false),
43
39
  definition('work_validate', 'Run targeted checks or read-only validation commands against a work handle with full current-state validation.', {
44
40
  session_id: sessionId, controller_id: { type: 'string', description: 'Controller identity that holds the Work lease. Defaults to the authenticated principal.' }, repo_id: repoId, work_id: workId, check_ids: { type: 'array', items: { type: 'string' } }, commands: { type: 'array', items: { type: 'object' } }, interactive_wait_ms: { type: 'number', description: 'Optional bounded attach window for checks launched by this validation call. Defaults to asynchronous behavior.' },
45
41
  }, ['work_id'], false),
@@ -52,7 +48,6 @@ const executionToolNames = new Set(executionToolDefinitions.map((tool) => tool.n
52
48
 
53
49
  /** Repository execution and validation remain Process/WorkHandle operations; semantic Work completion is separate. */
54
50
  const DURABLE_WORK_OPERATION_NAMES = new Set([
55
- 'work_execute',
56
51
  'work_validate',
57
52
  ]);
58
53
 
@@ -89,8 +84,8 @@ function inspectWork(ctx: MultiRepositoryMcpToolContext, args: Record<string, un
89
84
  const validationStarted = performance.now();
90
85
  const validated = validateWorkHandle(ctx.controllerHome, handle, identityFor(ctx, args), 'cheap', 'inspect');
91
86
  const validationMs = performance.now() - validationStarted;
92
- const status = repositoryGitStatus(validated.worktreeRepository);
93
- const diff = repositoryGitDiff(validated.worktreeRepository, { maxBytes: 64 * 1024 });
87
+ const candidate = repositoryGitWorkspaceChanges(validated.worktreeRepository);
88
+ const { status, diff } = candidate;
94
89
  const contract = contractFor(ctx, handle);
95
90
  const checks = contract?.checks ?? [];
96
91
  const packageManifest = existsSync(`${validated.worktreeRepository.canonicalRoot}/package.json`)
@@ -100,7 +95,7 @@ function inspectWork(ctx: MultiRepositoryMcpToolContext, args: Record<string, un
100
95
  session: { sessionId: session.sessionId, repoId: session.activeRepositoryId, checkoutId: session.activeCheckoutId },
101
96
  work: compactHandle(handle),
102
97
  readiness: { valid: true, warnings: validated.warnings, permissionSnapshotVersion: handle.permissionSnapshotVersion },
103
- git: { status, diff: { nameOnly: diff.nameOnly, stat: diff.stat, patch: diff.patch, truncated: diff.truncated } },
98
+ git: { status, diff: { ...diff, staged: { nameOnly: candidate.staged.nameOnly, stat: candidate.staged.stat, truncated: candidate.staged.truncated }, unstaged: { nameOnly: candidate.unstaged.nameOnly, stat: candidate.unstaged.stat, truncated: candidate.unstaged.truncated }, untracked: status.untracked } },
104
99
  workContract: contract ? {
105
100
  workId: contract.workId,
106
101
  state: contract.semanticState,
@@ -110,7 +105,7 @@ function inspectWork(ctx: MultiRepositoryMcpToolContext, args: Record<string, un
110
105
  semantics: buildWorkContinuationSnapshot(contract).semantics,
111
106
  } : undefined,
112
107
  continuation: contract ? buildWorkContinuationSnapshot(contract) : undefined,
113
- paths: { changed: diff.nameOnly },
108
+ paths: { changed: candidate.changedPaths },
114
109
  checks: checks.map((checkId) => ({ checkId, registered: listControllerChecks(validated.worktreeRepository.canonicalRoot).some((check) => check.id === checkId) })),
115
110
  package: packageManifest ? { name: packageManifest.name, scripts: packageManifest.scripts } : undefined,
116
111
  };
@@ -131,7 +126,6 @@ export async function callExecutionTool(ctx: MultiRepositoryMcpToolContext, name
131
126
  case 'session_bind_repository': return result(bindSessionRepository(ctx, args));
132
127
  case 'work_prepare': return result(prepareWork(ctx, args));
133
128
  case 'work_inspect': return result(inspectWork(ctx, args));
134
- case 'work_execute': return result(await executeWork(ctx, args));
135
129
  case 'work_validate': return result(await validateWork(ctx, args));
136
130
  case 'approval_resolve': {
137
131
  const session = requireSession(ctx, args);
@@ -141,15 +141,15 @@ export async function callPluginAdapter(
141
141
  switch (name) {
142
142
  case 'list_plugins': {
143
143
  const controllerPlugins = listControllerPluginManifests(ctx.controllerHome, {
144
- forceRefresh: true,
144
+ preferStored: true,
145
145
  }).map(summarizePlugin);
146
146
  let repositoryPlugins: ReturnType<typeof summarizePlugin>[] = [];
147
147
  let repositoryId: string | undefined;
148
- if (explicitRepositoryContextRequested(args)) {
148
+ if (explicitRepositoryContextRequested(args) || typeof ctx.repoId === 'string' && ctx.repoId.trim()) {
149
149
  const repository = selected(ctx, args);
150
150
  repositoryId = repository.repoId;
151
151
  repositoryPlugins = listAssistantPluginManifests(ctx.controllerHome, repository, {
152
- forceRefresh: true,
152
+ preferStored: true,
153
153
  }).map(summarizePlugin);
154
154
  }
155
155
  return result({
@@ -316,6 +316,19 @@ export async function callPluginAdapter(
316
316
  }
317
317
 
318
318
  const submitted = application.submitted;
319
+ if (submitted.receipt.status === 'failed' && submitted.receipt.effectOutcome !== 'outcome_unknown') {
320
+ return result({
321
+ accepted: true,
322
+ deduplicated: submitted.deduplicated,
323
+ scope: pluginScopeLabel(scope),
324
+ plugin: summarizePluginActionReceipt(submitted.manifest),
325
+ action: { actionId: submitted.action.actionId },
326
+ requestId: submitted.receipt.requestId,
327
+ receiptId: submitted.receipt.receiptId,
328
+ effectOutcome: submitted.receipt.effectOutcome ?? 'failed',
329
+ error: submitted.receipt.error ?? { code: 'PLUGIN_ACTION_FAILED', message: 'Plugin action failed.' },
330
+ }, true);
331
+ }
319
332
  const compactResult = compactSubmittedPluginActionResult(submitted.result);
320
333
  const value = {
321
334
  accepted: true,
@@ -53,27 +53,10 @@ const repoIdProp = {
53
53
  };
54
54
  const processIdProp = {
55
55
  type: 'string',
56
- description: 'Lightweight or durable process id returned by run_check / repository_command_execute.',
56
+ description: 'Process id returned by execute_command or run_check.',
57
57
  };
58
58
 
59
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
- ),
77
60
  definition(
78
61
  'run_check',
79
62
  '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.',
@@ -304,7 +287,6 @@ export async function callProcessTool(
304
287
  name: string,
305
288
  args: Record<string, unknown>,
306
289
  ): Promise<CallToolResult | undefined> {
307
- if (name === 'process_exec') return callProcessExecTool(ctx, args);
308
290
  // run_check shares this module's public schema, but its execution authority is
309
291
  // the Gateway check facade in router.ts. Only attachment/lifecycle operations
310
292
  // consume an existing process_id here.
@@ -383,7 +365,7 @@ export async function callProcessTool(
383
365
  }
384
366
 
385
367
  /**
386
- * `process_exec` — the canonical host-local command lane.
368
+ * Host target of the single execute_command entry: canonical process:exec Grant.
387
369
  *
388
370
  * Repo-less by construction: the Forge instance is the target and `cwd` is an
389
371
  * execution argument. Authorization is one explicit canonical `process:exec`
@@ -406,7 +388,7 @@ function workDefaultCommandCwd(ctx: MultiRepositoryMcpToolContext, workId: strin
406
388
  return workspace || undefined;
407
389
  }
408
390
 
409
- async function callProcessExecTool(
391
+ export async function executeAuthorizedHostCommand(
410
392
  ctx: MultiRepositoryMcpToolContext,
411
393
  args: Record<string, unknown>,
412
394
  ): Promise<CallToolResult> {
@@ -48,7 +48,6 @@ function result(value: Record<string, unknown>, isError = false): CallToolResult
48
48
 
49
49
  export function getMcpToolDefinition(ctx: MultiRepositoryMcpToolContext, name: string): McpToolDefinition | undefined {
50
50
  const currentDefinitions = [...runtimeToolDefinitions, ...executionToolDefinitions, ...processToolDefinitions, ...repositoryToolDefinitions];
51
- if (ctx.toolset !== 'full') return currentDefinitions.find((tool) => tool.name === name);
52
51
  return [...currentDefinitions, ...buildMultiRepositoryToolDefinitions(ctx)].find((tool) => tool.name === name);
53
52
  }
54
53
 
@@ -212,11 +211,11 @@ export async function routeDurableMcpCall(
212
211
  }, true);
213
212
  }
214
213
 
215
- // repository_command_execute has its own durable boundary: non-destructive
214
+ // execute_command has its own durable boundary: non-destructive
216
215
  // remote writes run through the durable Process Runtime, while destructive or
217
216
  // explicitly delegated commands are refused by the repository facade itself.
218
217
  // Do not intercept that tool with the retired ExecutionJob gate here.
219
- if (classification.path === 'durable' && executionJobCreationRetired() && name !== 'repository_command_execute') {
218
+ if (classification.path === 'durable' && executionJobCreationRetired() && name !== 'execute_command') {
220
219
  return result({
221
220
  accepted: false,
222
221
  mode: 'external_controller_required',
@@ -227,8 +226,7 @@ export async function routeDurableMcpCall(
227
226
  ...(classification.decision ? { decision: classification.decision } : {}),
228
227
  },
229
228
  rejectCode: 'EXECUTION_JOB_RETIRED',
230
- message: 'This operation requires an explicit external Controller or domain capability; the Kernel no longer creates ExecutionJobs or a Work-ownership phase.',
231
- suggestedOperation: 'Create or resume semantic Work only when durable context is useful, then use the direct Process/domain capability or rh_work.launcher_start.',
229
+ message: 'This operation needs external Controller or authorized domain capability; Forge does not create Work/Plans or prescribe a workflow to fulfill it.',
232
230
  });
233
231
  }
234
232
 
@@ -7,7 +7,7 @@ import { classifyRepositoryCommandRoute } from '../../../src/runtime/execution/p
7
7
  import { isProcessIsolatedReadDiagnostic } from '../../../src/runtime/diagnostics/process-facade';
8
8
 
9
9
  /** Pure deterministic MCP Gateway placement policy. No execution or lifecycle mutation belongs here. */
10
- const DIRECT_REPOSITORY_TOOLS = new Set(['repository_list', 'repository_get', 'repository_workbench', 'repository_command_preview']);
10
+ const DIRECT_REPOSITORY_TOOLS = new Set(['repository_list', 'repository_get', 'repository_workbench']);
11
11
  const DIRECT_CONTROL_WRITE_TOOLS = new Set([
12
12
  'runtime_maintenance_apply',
13
13
  // Protected credential preparation and physical input own their authorization boundary.
@@ -21,7 +21,7 @@ const DIRECT_CONTROL_WRITE_TOOLS = new Set([
21
21
  ]);
22
22
 
23
23
  const THIN_ROUTED_TOOLS = new Set([
24
- 'repository_command_execute',
24
+ 'execute_command',
25
25
  'repository_safe_patch_apply',
26
26
  'repository_safe_patch_plan',
27
27
  'capability_execute',
@@ -128,8 +128,8 @@ const GATEWAY_ROUTE_BEHAVIOR_PROBES: ReadonlyArray<{
128
128
  }> = [
129
129
  { id: 'hot-read', operation: 'controller_ready', args: {} },
130
130
  { id: 'isolated-read-diagnostic', operation: 'workflow_watchdog_report', args: {} },
131
- { id: 'readonly-command', operation: 'repository_command_execute', args: { command: ['git', 'status', '--short'] } },
132
- { id: 'managed-local-command', operation: 'repository_command_execute', args: { command: ['bun', 'run', 'check:type'], timeout_ms: 120_000 } },
131
+ { id: 'readonly-command', operation: 'execute_command', args: { command: ['git', 'status', '--short'] } },
132
+ { id: 'managed-local-command', operation: 'execute_command', args: { command: ['bun', 'run', 'check:type'], timeout_ms: 120_000 } },
133
133
  { id: 'focused-check', operation: 'run_check', args: { check_id: 'package:check:type' } },
134
134
  { id: 'release-check', operation: 'run_check', args: { check_id: 'package:check:release' } },
135
135
  { id: 'interactive-write', operation: 'repository_safe_patch_apply', args: { operations: [] } },
@@ -311,7 +311,7 @@ export function classifyGatewayExecutionPath(
311
311
  };
312
312
  }
313
313
  const selfManagedProcessAsync = (
314
- name === 'repository_command_execute'
314
+ name === 'execute_command'
315
315
  || name === 'run_check'
316
316
  || name === 'verify_edit_session'
317
317
  ) && (
@@ -394,11 +394,18 @@ export function classifyGatewayExecutionPath(
394
394
  };
395
395
  }
396
396
 
397
- // repository_command_execute has one authoritative classifier. Process Runtime
398
- // owns every local single-process command regardless of timeout. Async requests
399
- // stay here and return a handle; explicit durable mode remains an external-
400
- // Controller boundary.
401
- if (name === 'repository_command_execute') {
397
+ // Host commands are already placed explicitly by the model and authorized
398
+ // by the ForgeInstance process:exec Grant. Never route them through a
399
+ // repository classifier or infer a Work/Plan from the shell command.
400
+ if (name === 'execute_command' && args.scope === 'host') {
401
+ return { path: 'fast', reasons: ['explicit_host_process_runtime'] };
402
+ }
403
+ if (name === 'execute_command' && args.dry_run === true) {
404
+ return { path: 'direct', reasons: ['explicit_command_preview_only'] };
405
+ }
406
+ // Repository commands use the existing Process Runtime classifier only for
407
+ // process handling and mechanical write protection.
408
+ if (name === 'execute_command') {
402
409
  const command = args.command;
403
410
  if (!(typeof command === 'string' || Array.isArray(command))) {
404
411
  return { path: 'reject', reasons: ['repository_command_missing'] };
@@ -2,7 +2,7 @@ import { existsSync } from 'fs';
2
2
  import { collectRuntimePerformanceDiagnostics, inferLocalControllerProcess } from '../../../src/runtime/diagnostics/performance';
3
3
  import type { McpToolDefinition, CallToolResult } from '../../../packages/protocols/mcp/tool-contract';
4
4
  import type { MultiRepositoryMcpToolContext } from '../multi-repository';
5
- import { allControllerToolDefinitions, controllerExposureSnapshot, controllerToolSurfaceStatus } from '../toolset';
5
+ import { controllerExposureSnapshot, controllerToolSurfaceStatus } from '../toolset';
6
6
  import { boundedPluginArtifactImageContent, jsonPreview, result, resultWithPluginArtifactImages } from './result-adapter';
7
7
  import { expectedRevision, repositoryRootForRepoId, selected, stringList } from './shared-adapter';
8
8
  import { callStatusInboxAdapter, GIT_IDENTITY_SAMPLE_TTL_MS, summarizeInvalidActiveWorkCandidate, summarizeWorkListItem } from './status-inbox-adapter';
@@ -43,11 +43,12 @@ export const runtimeToolDefinitions: McpToolDefinition[] = [
43
43
  detail_level: { type: 'string', enum: ['summary', 'detail'] },
44
44
  limit: { type: 'number' },
45
45
  }),
46
- definition('rh_context', 'Preferred ChatGPT facade and default repository code-discovery/read path. Semantic task/capability queries can also recall an initial bounded, relevance-gated Cognitive advisory working set when Project/Workspace scope is available. That first pack is an attention envelope, never a claim that the top N items are cognitively complete. Reuse it through routine micro-steps; when the model judges prior context insufficient, progressively narrow/expand recall with another semantic query or explicit knowledge audit. Start broad once to combine heuristic lexical discovery, current raw source, and optional CodeGraph structural evidence with few round trips. Natural-language lexical terms are discovery hints: do not require every guessed term to match and do not repeat the same broad search merely because a heuristic term missed. After credible files or symbols are found, derive follow-up paths/symbols from the returned source and prefer known_paths, compiler semantic_navigation/@tsnav for TypeScript, or structural relationships before another broad lexical pass. Call rh_context repeatedly only when that progressive expansion can materially improve correctness; follow-ups reuse session-scoped evidence when source identity is unchanged. Shell rg/grep/sed/cat loops are fallback-only when this Context Plane cannot supply the needed evidence.', {
46
+ definition('rh_context', 'Read-only semantic repository retrieval and advisory context, including source snippets, paths, symbols, relationships and optional project knowledge. The model chooses when to retrieve context, when to use terminal search through execute_command, and whether the retrieved evidence is sufficient. This tool does not authorize execution or impose a required workflow.', {
47
47
  repo_id: repoId,
48
48
  checkout_id: { type: 'string', description: 'Optional checkout identity for repositories with multiple worktrees.' },
49
- operation: { type: 'string', enum: ['list', 'get', 'search'], description: 'Defaults to get. Use search as the default code-location path when an exact file is unknown.' },
49
+ operation: { type: 'string', enum: ['list', 'get', 'search'], description: 'Defaults to get. Search returns semantic source candidates when the model selects this retrieval capability.' },
50
50
  query: { type: 'string', description: 'Code/content intent for operation=search. For operation=list, a natural-language capability intent such as "configure Xcode provisioning" returns ranked read-only capability candidates while execution remains on the capability\'s typed executor. Frozen-schema clients may append @tsnav or @swiftnav references|definition|implementations <repo-path>:<line>:<column> for compiler/LSP-backed semantic navigation.' },
51
+ search_terms: { type: 'array', maxItems: 8, items: { type: 'string', maxLength: 160 }, description: 'Optional model-selected literal code-search terms, ordered by likely relevance. Preserve query as the original user intent; for non-English or descriptive questions about source written in another language, infer repository-language identifiers/phrases (such as the relevant function name, file symbol, or operation keyword) and supply them here. Forge uses bounded lexical ripgrep matching, not automatic translation or semantic embeddings. Refine terms or known_paths when initial candidates are insufficient.' },
51
52
  include_learning_recall: { type: 'boolean', description: 'Defaults to true for semantic task/capability queries. Set false for routine progressive source follow-ups or micro-steps when the already recalled working set is still valid. This is a model-owned attention/cadence choice, not a Forge semantic trigger.' },
52
53
  knowledge_query: { type: 'string', description: 'Optional explicit read-only Cognitive audit query. Ordinary code/capability intent queries already receive a bounded relevant-learning recall; use this field for deliberate memory inspection. May be used without code query. Use "*" or omit text with filters to list learned advisory memory in scopes reachable from this repo/Work.' },
53
54
  knowledge_memory_id: { type: 'string', description: 'Optional exact Cognitive memory id for inspection.' },
@@ -63,7 +64,7 @@ export const runtimeToolDefinitions: McpToolDefinition[] = [
63
64
  exclude_globs: { type: 'array', items: { type: 'string' } },
64
65
  retrieval_mode: { type: 'string', enum: ['implementation', 'plan', 'debug', 'review'], description: 'Defaults to implementation. Implementation returns current raw impact evidence for ChatGPT to judge; plan/debug/review intentionally widen evidence.' },
65
66
  impact_domains: { type: 'array', items: { type: 'string', enum: [...CONTROLLER_CONTEXT_IMPACT_DOMAINS] }, description: 'Optional GPT-selected cross-cutting evidence dimensions. Forge expands these mechanically in the same retrieval call; it never treats them as proof of semantic completeness.' },
66
- structural_context: { type: 'string', enum: ['off', 'auto', 'required'], description: 'Optional override. Defaults to auto for implementation/review and required for plan/debug.' },
67
+ structural_context: { type: 'string', enum: ['off', 'auto', 'required'], description: 'Optional override. Defaults to off for all modes; explicitly opt in only for structural investigations.' },
67
68
  semantic_navigation: {
68
69
  type: 'array',
69
70
  maxItems: 8,
@@ -292,13 +293,13 @@ export const runtimeToolDefinitions: McpToolDefinition[] = [
292
293
  min_age_minutes: { type: 'number' },
293
294
  max_candidates: { type: 'number' },
294
295
  }, ['action_id'], false),
295
- definition('runtime_maintenance_status', 'Read the self-contained runtime maintenance plan without using repository_command_execute or Local Job tickets.', {
296
+ definition('runtime_maintenance_status', 'Read the self-contained runtime maintenance plan without invoking execute_command or creating Local Job tickets.', {
296
297
  repo_id: repoId,
297
298
  min_age_minutes: { type: 'number' },
298
299
  max_candidates: { type: 'number' },
299
300
  cancel_pending_approvals: { type: 'boolean' },
300
301
  }),
301
- definition('runtime_maintenance_apply', 'Apply one bounded runtime maintenance action without repository_command_execute or Local Job tickets.', {
302
+ definition('runtime_maintenance_apply', 'Apply one bounded runtime maintenance action without invoking execute_command or creating Local Job tickets.', {
302
303
  repo_id: repoId,
303
304
  action_id: { type: 'string', enum: ['local_jobs_reconcile', 'quarantine_unreadable_local_jobs', 'runtime_storage_finalize_relocation', 'rebuild_projection', 'full_maintenance_pass'] },
304
305
  confirm_maintenance: { type: 'boolean' },
@@ -355,7 +356,7 @@ export const runtimeToolDefinitions: McpToolDefinition[] = [
355
356
  max_candidates: { type: 'number' },
356
357
  confirm_repair: { type: 'boolean' },
357
358
  }, ['confirm_repair'], false),
358
- definition('list_plugins', 'List repository plugins, or controller-scoped plugins when repo_id is omitted.', {
359
+ definition('list_plugins', 'List controller plugins and the selected repository plugins. When repo_id is omitted, the current repository context is included automatically; with multiple repositories, provide repo_id. Uses registered manifest snapshots with last-observed capability health; action execution independently validates provider identity and readiness.', {
359
360
  repo_id: repoId,
360
361
  }),
361
362
  definition('get_plugin', 'Read one repository or controller-scoped plugin manifest including action schemas and policy requirements.', {
@@ -453,8 +454,11 @@ export const runtimeToolDefinitions: McpToolDefinition[] = [
453
454
  recent_safe_error: { type: 'string' },
454
455
  model: { type: 'string' },
455
456
  }),
456
- definition('supervisor_task', 'Start, list, inspect, revise, recover, stop, or prove standalone Workflow Supervisor autonomous tasks. Supervisor task/effect state is the continuation authority; Requirement, Plan, and Work are optional and are not created by this tool.', {
457
- repo_id: { ...repoId, description: 'Optional repository provenance for start/proof; never Work authority.' },
457
+ definition('supervisor_task', 'Start, list, inspect, revise, recover, stop, or prove standalone Workflow Supervisor autonomous tasks. Supervisor task/effect state is the continuation authority; Requirement, Plan, and Work are not created by this tool. A standalone task may bind to one existing Work or Requirement for semantic DONE proof; omitting both keeps the unbound standalone contract.', {
458
+ repo_id: { ...repoId, description: 'Optional repository provenance for start/proof; a repository scope must be available with work_id or requirement_id. Repository identity alone is never Work authority.' },
459
+ work_id: { type: 'string', minLength: 1, maxLength: 256, description: 'For start, bind the task to this exact Work; for revise, one-way bind an existing unbound task using expected_completion_contract_sha256.' },
460
+ requirement_id: { type: 'string', minLength: 1, maxLength: 256, description: 'For start, bind the task to this exact Requirement; for revise, one-way bind an existing unbound task using expected_completion_contract_sha256. Mutually exclusive with work_id.' },
461
+ expected_completion_contract_sha256: { type: 'string', description: 'For revise with work_id or requirement_id, CAS fingerprint returned by supervisor_task get as completionContractSha256.' },
458
462
  operation: { type: 'string', enum: ['start', 'list', 'get', 'revise', 'recover', 'stop', 'proof'] },
459
463
  task_id: { type: 'string' },
460
464
  objective: { type: 'string', description: 'Outcome objective for start/revise; revise never changes task or conversation identity.' },
@@ -463,7 +467,8 @@ export const runtimeToolDefinitions: McpToolDefinition[] = [
463
467
  source_effect_id: { type: 'string', description: 'Optional exact source effect for operator recovery fencing.' },
464
468
  supersede_unknown: { type: 'boolean', description: 'For recover only: explicitly retire one outcome-unknown effect instead of replaying it.' },
465
469
  authorized_by: { type: 'string', description: 'Optional operator identity recorded by canonical recovery authority.' },
466
- active_only: { type: 'boolean', description: 'For list, defaults true; exclude terminal tasks.' },
470
+ active_only: { type: 'boolean', description: 'For list, defaults true; exclude terminal tasks. Set false for legacy all-task listing.' },
471
+ terminal_only: { type: 'boolean', description: 'For list, return only canonically terminal DONE/NEEDS_USER/STOPPED task history with exact task and terminal status; does not archive ChatGPT conversations.' },
467
472
  request_id: { type: 'string', description: 'Stable idempotency identity for start/revise/recover.' },
468
473
  active_release_id: { type: 'string', description: 'Active Runtime release expected in proof dispatch evidence.' },
469
474
  not_before: { type: 'string', description: 'ISO-8601 lower bound for proof completions.' },
@@ -22,7 +22,6 @@ export {
22
22
  runtimeToolDefinitions,
23
23
  } from './runtime-tool-definitions';
24
24
  import { callWorkAdapter, runFacadeRepair } from './work-adapter';
25
- import { automationMetadata, persistAutomationReceipt } from './automation-receipt-adapter';
26
25
 
27
26
  async function callRuntimeToolUnchecked(ctx: MultiRepositoryMcpToolContext, name: string, args: Record<string, unknown>): Promise<CallToolResult | undefined> {
28
27
  try {
@@ -68,10 +67,7 @@ async function callRuntimeToolUnchecked(ctx: MultiRepositoryMcpToolContext, name
68
67
  }
69
68
 
70
69
  export async function callRuntimeTool(ctx: MultiRepositoryMcpToolContext, name: string, args: Record<string, unknown>): Promise<CallToolResult | undefined> {
71
- const metadata = automationMetadata(args);
72
- const outcome = await callRuntimeToolUnchecked(ctx, name, args);
73
- await persistAutomationReceipt(ctx, name, metadata, outcome);
74
- return outcome;
70
+ return callRuntimeToolUnchecked(ctx, name, args);
75
71
  }
76
72
 
77
73
  export { runtimeIdentitySnapshot, dispatchedChatgptRelayAuthorizesStaleControllerRecovery, sessionlessFacadeControllerAuthorityMatches } from './controller-authority-adapter';
@@ -3,6 +3,7 @@ import type { MultiRepositoryMcpToolContext } from '../multi-repository';
3
3
  import { applyScheduleDedupe, buildScheduleDedupeReport, deleteSchedule } from '../../../packages/kernel/scheduler/api/index';
4
4
  import { buildFacadeResult } from '../../../src/runtime/control-plane/facade/facade-result';
5
5
  import { buildWorkContinuationSnapshot } from '../../../src/runtime/control-plane/facade/work-continuation';
6
+ import { bindWorkflowSupervisorScheduledWakeForWork } from '../../../src/runtime/root/workflow-supervisor-composition';
6
7
  import {
7
8
  createWorkContinuationSchedule,
8
9
  getWorkContinuationSchedule,
@@ -34,6 +35,34 @@ const RH_WORK_SCHEDULE_OPERATIONS = new Set<RhWorkScheduleOperation>([
34
35
  'schedule_trigger',
35
36
  ]);
36
37
 
38
+ async function bindSupervisorWakeForSchedule(
39
+ ctx: MultiRepositoryMcpToolContext,
40
+ repoId: string,
41
+ schedule: { scheduleId: string; action: { operation: string; arguments?: Record<string, unknown> } },
42
+ ): Promise<{ status: 'bound' | 'not_enrolled' | 'binding_deferred'; taskId?: string } | undefined> {
43
+ if (schedule.action.operation !== 'controller_progression' || schedule.action.arguments?.controller_type !== 'chatgpt') {
44
+ return undefined;
45
+ }
46
+ const workId = typeof schedule.action.arguments.work_id === 'string' ? schedule.action.arguments.work_id.trim() : '';
47
+ if (!workId) throw new Error('SCHEDULE_SUPERVISOR_WAKE_WORK_ID_REQUIRED');
48
+ try {
49
+ return await bindWorkflowSupervisorScheduledWakeForWork(
50
+ { controllerHome: ctx.controllerHome, repoId },
51
+ workId,
52
+ schedule.scheduleId,
53
+ );
54
+ } catch (error) {
55
+ const reason = error instanceof Error ? error.message : String(error);
56
+ let pauseFailure = '';
57
+ try {
58
+ pauseWorkContinuationSchedule(ctx.controllerHome, repoId, schedule.scheduleId, `Supervisor scheduled-wake binding failed: ${reason}`);
59
+ } catch (pauseError) {
60
+ pauseFailure = `; schedule pause also failed: ${pauseError instanceof Error ? pauseError.message : String(pauseError)}`;
61
+ }
62
+ throw new Error(`SCHEDULE_SUPERVISOR_WAKE_BINDING_FAILED:${reason}${pauseFailure}`);
63
+ }
64
+ }
65
+
37
66
  export function isRhWorkScheduleOperation(operation: string): operation is RhWorkScheduleOperation {
38
67
  return RH_WORK_SCHEDULE_OPERATIONS.has(operation as RhWorkScheduleOperation);
39
68
  }
@@ -105,6 +134,7 @@ export async function callRhWorkScheduleAdapter(
105
134
  backoffMaxMinutes: typeof args.backoff_max_minutes === 'number' ? args.backoff_max_minutes : undefined,
106
135
  stopConditions: Array.isArray(args.stop_conditions) ? args.stop_conditions.map(String) : undefined,
107
136
  });
137
+ const supervisorWakeBinding = await bindSupervisorWakeForSchedule(ctx, repository.repoId, created.schedule);
108
138
  return result(buildFacadeResult({
109
139
  summary: created.work
110
140
  ? `Work schedule ${created.schedule.scheduleId} is configured for Work ${created.work.workId}.`
@@ -112,6 +142,7 @@ export async function callRhWorkScheduleAdapter(
112
142
  data: {
113
143
  schedule: created.schedule,
114
144
  ...(created.work ? { work: buildWorkContinuationSnapshot(created.work) } : {}),
145
+ ...(supervisorWakeBinding ? { supervisorWakeBinding } : {}),
115
146
  },
116
147
  }) as unknown as Record<string, unknown>);
117
148
  }
@@ -134,7 +165,11 @@ export async function callRhWorkScheduleAdapter(
134
165
  }
135
166
  if (operation === 'schedule_resume') {
136
167
  const saved = resumeWorkContinuationSchedule(ctx.controllerHome, repository.repoId, scheduleId);
137
- return result(buildFacadeResult({ summary: `Schedule ${scheduleId} is resumed.`, data: { schedule: saved } }) as unknown as Record<string, unknown>);
168
+ const supervisorWakeBinding = await bindSupervisorWakeForSchedule(ctx, repository.repoId, saved);
169
+ return result(buildFacadeResult({
170
+ summary: `Schedule ${scheduleId} is resumed.`,
171
+ data: { schedule: saved, ...(supervisorWakeBinding ? { supervisorWakeBinding } : {}) },
172
+ }) as unknown as Record<string, unknown>);
138
173
  }
139
174
  if (operation === 'schedule_delete') {
140
175
  const schedule = getWorkContinuationSchedule(ctx.controllerHome, repository.repoId, scheduleId).schedule;
@@ -2,7 +2,7 @@ import { existsSync } from "fs";
2
2
  import { join } from "path";
3
3
  import { runProcess } from '../../../src/effects/process-runner';
4
4
  import type { MultiRepositoryMcpToolContext } from "../multi-repository";
5
- import { allControllerToolDefinitions, controllerExposureSnapshot, controllerToolSurfaceStatus } from "../toolset";
5
+ import { controllerExposureSnapshot, controllerToolSurfaceStatus } from "../toolset";
6
6
  import { result } from "./result-adapter";
7
7
  import { selected, selectedOptional } from "./shared-adapter";
8
8
  import { SEMANTIC_SCOPE_KEY } from "../../../src/cli/repositories/controller-home";
@@ -16,7 +16,8 @@ import { cachedGitIdentity, gitSnapshot } from "../../../src/cli/repository/insp
16
16
  import { buildRuntimeMaintenanceStatus } from "../../../src/runtime/recovery";
17
17
  import { allowedFacadeOperations, buildFacadeResult, listCapabilityDescriptors, summarizeCapabilityGroups, listHandoffAttentionItems, normalizeCheckIds, buildWorkContinuationSnapshot, listPlanContracts, summarizePlanContract, runHandoffInboxApplication, type FacadeTool } from "../../../src/runtime/control-plane/facade";
18
18
  import { buildJobOperationDigest } from '../../../src/runtime/control-plane/facade/operation-digest';
19
- import { readActiveWorkCandidates, type InvalidActiveWorkCandidate } from "../../../packages/kernel/work/api/index";
19
+ import { getWorkContract, readActiveWorkCandidates, semanticWorkState, type InvalidActiveWorkCandidate } from "../../../packages/kernel/work/api/index";
20
+ import { listWorkHandles } from '../../../src/runtime/control-plane/execution/work-handle-store';
20
21
  import { observeRuntimeStatus } from "../../../src/runtime/root/status";
21
22
  import { getControllerSession } from "../../../packages/kernel/controller/api/index";
22
23
  import { listActiveOccurrences, listSchedules, scheduleOwnsWork } from "../../../packages/kernel/scheduler/api/index";
@@ -447,6 +448,7 @@ export async function callStatusInboxAdapter(
447
448
  detailTimingMark = now;
448
449
  };
449
450
  const readiness = await controllerReadinessEvidence(ctx, repository);
451
+ const runtimeObservation = observeRuntimeStatus(ctx.controllerHome);
450
452
  markDetailPhase('readiness');
451
453
  const liveGit = gitSnapshot(repository.canonicalRoot);
452
454
  markDetailPhase('git');
@@ -455,7 +457,7 @@ export async function callStatusInboxAdapter(
455
457
  const runtimeSource = runtimeSourceSnapshotStatus(readiness.daemon.source, ctx.runtimeSourceRoot);
456
458
  const sourceSnapshotStale = runtimeSource.restartRequired;
457
459
  const exposure = controllerExposureSnapshot(ctx);
458
- const localRegisteredToolNames = allControllerToolDefinitions(ctx).map((tool) => tool.name).sort();
460
+ const localRegisteredToolNames = [...exposure.actualToolNames].sort();
459
461
  markDetailPhase('tool_surface');
460
462
  const toolSurfaceReady = exposure.ready && exposure.missingToolNames.length === 0;
461
463
  // Ordinary interactive execution depends on the execution axis only.
@@ -582,7 +584,7 @@ export async function callStatusInboxAdapter(
582
584
  )],
583
585
  diagnostics: {
584
586
  runtime: {
585
- ready: readiness.ready,
587
+ ready: runtimeObservation.ready,
586
588
  },
587
589
  toolSurface: {
588
590
  ready: toolSurfaceReady,
@@ -644,6 +646,39 @@ export async function callStatusInboxAdapter(
644
646
  const pendingHandoffCount = pendingHandoffAttention.length;
645
647
  const activeWorkProjection = readActiveWorkCandidates({ ...store, limit: 200 });
646
648
  const activeContracts = activeWorkProjection.contracts;
649
+ // Reuse the exact WorkHandle and semantic Work authorities consulted by
650
+ // delivery. This is a read-only diagnosis, never a delivery admission gate.
651
+ const receivingOwners = detailLevel === 'detail'
652
+ ? listWorkHandles(ctx.controllerHome, repository.repoId)
653
+ .filter((handle) => {
654
+ if (handle.checkoutId !== repository.activeCheckoutId
655
+ || handle.branch !== liveGit.branch
656
+ || handle.state === 'cleaned' || handle.state === 'failed') return false;
657
+ const contract = getWorkContract(store, handle.workContractId ?? handle.workId);
658
+ return Boolean(contract && semanticWorkState(contract) === 'open');
659
+ })
660
+ .sort((left, right) => left.workId.localeCompare(right.workId))
661
+ : [];
662
+ const headDriftedOwners = receivingOwners.filter((handle) =>
663
+ Boolean(handle.expectedHead && handle.expectedHead !== liveGit.head));
664
+ const repositoryDeliveryBlockers = [
665
+ ...(receivingOwners.length > 1 ? ['WORK_CANONICAL_MUTATION_OWNERSHIP_AMBIGUOUS']
666
+ : receivingOwners.length ? ['WORK_DELIVERY_TARGET_WORK_ACTIVE'] : []),
667
+ ...(headDriftedOwners.length ? ['WORK_HANDLE_HEAD_CHANGED'] : []),
668
+ ...(liveGit.dirty ? ['WORK_DELIVERY_TARGET_DIRTY'] : []),
669
+ ];
670
+ const repositoryDeliveryNextSafeAction =
671
+ receivingOwners.length > 1
672
+ ? 'Multiple open WorkHandles claim this checkout. Resolve canonical ownership before any Git mutation; do not guess or bypass a writer.'
673
+ : headDriftedOwners.length && liveGit.dirty
674
+ ? 'Owning Work: review the uncommitted paths against successor commits, converge its edits, then use explicit work_prepare successor adoption only if ancestry and path disjointness are proven.'
675
+ : headDriftedOwners.length
676
+ ? 'Owning Work: verify exact HEAD ancestry and use work_prepare with expected_previous_head/adopt_candidate_head; never silently rebase or reset.'
677
+ : liveGit.dirty
678
+ ? 'Owning writer: review and verify the existing dirty paths, then commit through its authorized Work before integrating another candidate; never auto-stash or reset.'
679
+ : receivingOwners.length
680
+ ? 'The receiving Work owns this checkout. Integrate reviewed source commits using its own authorized Git path, then reconcile each source Work through canonical deliver_work.'
681
+ : 'For a validated source Work, use canonical repository.git.deliver_work; this read-only projection does not check live mutation leases or grant integration authority.';
647
682
  markDetailPhase('work_state');
648
683
  const activePrimaryWork = activeContracts.filter((contract) => (contract.lifecycleRole ?? 'primary') === 'primary');
649
684
  const activeExecutionChildren = activeContracts.filter((contract) => contract.lifecycleRole === 'execution_child');
@@ -743,6 +778,25 @@ export async function callStatusInboxAdapter(
743
778
  primaryWorkActivityCounts,
744
779
  primaryWorkActivities,
745
780
  activeContractCount: activeContracts.length,
781
+ ...(detailLevel === 'detail' ? { repositoryDelivery: {
782
+ observation: 'work_handle_and_git_snapshot' as const,
783
+ diagnosticOnly: true,
784
+ checkoutId: repository.activeCheckoutId,
785
+ branch: liveGit.branch,
786
+ head: liveGit.head,
787
+ dirty: liveGit.dirty,
788
+ ownerCount: receivingOwners.length,
789
+ ownersTruncated: receivingOwners.length > 5,
790
+ owners: receivingOwners.slice(0, 5).map((handle) => ({
791
+ workId: handle.workId,
792
+ state: handle.state,
793
+ expectedHead: handle.expectedHead ?? null,
794
+ headDrift: Boolean(handle.expectedHead && handle.expectedHead !== liveGit.head),
795
+ })),
796
+ blockers: repositoryDeliveryBlockers,
797
+ nextSafeAction: repositoryDeliveryNextSafeAction,
798
+ limitations: 'Live leases, source validation, conflict preview and target CAS remain canonical delivery-time checks.',
799
+ } } : {}),
746
800
  invalidActiveContractCount: activeWorkProjection.invalid.length,
747
801
  invalidActiveContracts: activeWorkProjection.invalid.slice(0, 10).map(summarizeInvalidActiveWorkCandidate),
748
802
  // Summary keeps the stable facade surface only; detail expands to the full registered schema.
@@ -10,9 +10,10 @@ import {
10
10
  navigateTypeScriptSymbol,
11
11
  type TypeScriptNavigationRequest,
12
12
  } from '../../../src/runtime/context/typescript-navigation';
13
- import type {
14
- SemanticNavigationOutcome,
15
- SemanticNavigationReadPolicy,
13
+ import {
14
+ isIncidentalSemanticDependencyProbe,
15
+ type SemanticNavigationOutcome,
16
+ type SemanticNavigationReadPolicy,
16
17
  } from '../../../src/runtime/context/semantic-navigation-contract';
17
18
 
18
19
  interface Envelope {
@@ -83,6 +84,7 @@ export function runTypeScriptNavigationSidecar(
83
84
  try {
84
85
  for (const request of envelope.requests) {
85
86
  let policyDeniedReads = 0;
87
+ let materialPolicyDeniedReads = 0;
86
88
  const policyDeniedReadSamples = new Set<string>();
87
89
  try {
88
90
  const result = navigateTypeScriptSymbol(repoRoot, request, {
@@ -92,6 +94,7 @@ export function runTypeScriptNavigationSidecar(
92
94
  const decision = resolveMcpPath(repoRoot, relativePath, policy, 'read');
93
95
  if (decision.ok) return true;
94
96
  policyDeniedReads += 1;
97
+ if (!isIncidentalSemanticDependencyProbe(relativePath)) materialPolicyDeniedReads += 1;
95
98
  if (policyDeniedReadSamples.size < 20) policyDeniedReadSamples.add(relativePath);
96
99
  return false;
97
100
  },
@@ -105,6 +108,7 @@ export function runTypeScriptNavigationSidecar(
105
108
  target: result.target,
106
109
  locations: result.locations,
107
110
  policyDeniedReads,
111
+ materialPolicyDeniedReads,
108
112
  ...(policyDeniedReadSamples.size > 0 ? {
109
113
  details: { policyDeniedReadSamples: [...policyDeniedReadSamples] },
110
114
  } : {}),