@moretea-labs/forge 1.8.0 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (528) hide show
  1. package/AGENTS.md +70 -7
  2. package/CHANGELOG.md +14 -0
  3. package/CLAUDE.md +17 -2
  4. package/CONTRIBUTING.md +3 -2
  5. package/THIRD_PARTY_NOTICES.md +1 -1
  6. package/adapters/chatgpt/browser-delivery-host.ts +7 -1
  7. package/adapters/chatgpt/browser-delivery-runtime.ts +529 -56
  8. package/adapters/chatgpt/controller-binding-store.ts +101 -22
  9. package/adapters/chatgpt/controller-round-host.ts +15 -25
  10. package/adapters/chatgpt/controller-round-settlement-store.ts +58 -4
  11. package/adapters/chatgpt/provider-delivery.ts +228 -1
  12. package/adapters/chatgpt/work-conversation-binding-store.ts +79 -53
  13. package/adapters/computer/chatgpt-extension-target.ts +463 -0
  14. package/adapters/computer/chatgpt-target-router.ts +103 -0
  15. package/adapters/computer/chrome-extension/background.js +385 -0
  16. package/adapters/computer/chrome-extension/content.js +378 -0
  17. package/adapters/computer/chrome-extension/core.js +24 -0
  18. package/adapters/computer/chrome-extension/manifest.json +30 -0
  19. package/adapters/computer/desktop-operator-discovery.ts +11 -31
  20. package/adapters/computer/interaction-target-authority.ts +142 -18
  21. package/adapters/mcp/auth.ts +0 -1
  22. package/adapters/mcp/instructions.ts +5 -4
  23. package/adapters/mcp/multi-repository.ts +3 -19
  24. package/adapters/mcp/oauth.ts +73 -0
  25. package/adapters/mcp/paths.ts +4 -1
  26. package/adapters/mcp/runtime-gateway/automation-receipt-adapter.ts +87 -0
  27. package/adapters/mcp/runtime-gateway/bounded-result-runtime.ts +62 -0
  28. package/adapters/mcp/runtime-gateway/cognition-settlement.ts +201 -0
  29. package/adapters/mcp/runtime-gateway/context-adapter.ts +411 -73
  30. package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +91 -0
  31. package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +20 -5
  32. package/adapters/mcp/runtime-gateway/core-capability-adapter.ts +258 -0
  33. package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +10 -27
  34. package/adapters/mcp/runtime-gateway/engineering-tool-contract.ts +15 -0
  35. package/adapters/mcp/runtime-gateway/execution-tools.ts +8 -42
  36. package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +2 -1
  37. package/adapters/mcp/runtime-gateway/plugin-adapter.ts +117 -45
  38. package/adapters/mcp/runtime-gateway/process-tools.ts +190 -22
  39. package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +16 -4
  40. package/adapters/mcp/runtime-gateway/recovery-adapter.ts +69 -52
  41. package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +4 -35
  42. package/adapters/mcp/runtime-gateway/result-adapter.ts +10 -4
  43. package/adapters/mcp/runtime-gateway/router.ts +18 -504
  44. package/adapters/mcp/runtime-gateway/routing-policy.ts +499 -0
  45. package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +14 -65
  46. package/adapters/mcp/runtime-gateway/runtime-readiness-observation.ts +218 -0
  47. package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +113 -173
  48. package/adapters/mcp/runtime-gateway/runtime-tools.ts +15 -5
  49. package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +1 -0
  50. package/adapters/mcp/runtime-gateway/shared-adapter.ts +20 -0
  51. package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +358 -266
  52. package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +136 -0
  53. package/adapters/mcp/runtime-gateway/work-adapter.ts +261 -3122
  54. package/adapters/mcp/runtime-gateway/work-controller-operations.ts +257 -0
  55. package/adapters/mcp/runtime-gateway/work-detail-projection.ts +60 -0
  56. package/adapters/mcp/runtime-gateway/work-input-wire-migration.ts +246 -0
  57. package/adapters/mcp/runtime-gateway/work-learning-operations.ts +145 -0
  58. package/adapters/mcp/runtime-gateway/work-list-projection.ts +38 -0
  59. package/adapters/mcp/runtime-gateway/work-plan-operations.ts +382 -0
  60. package/adapters/mcp/runtime-gateway/work-repair-adapter.ts +308 -0
  61. package/adapters/mcp/runtime-gateway/work-requirement-operations.ts +148 -0
  62. package/adapters/mcp/runtime-gateway/work-semantic-operations.ts +263 -0
  63. package/adapters/mcp/runtime-gateway/work-workflow-operations.ts +113 -0
  64. package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +156 -0
  65. package/adapters/mcp/server.ts +67 -23
  66. package/adapters/mcp/setup.ts +1 -3
  67. package/adapters/mcp/tool-mapping/legacy-tool-service.ts +44 -170
  68. package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +4 -9
  69. package/adapters/mcp/tool-mapping/repository-tools.ts +133 -142
  70. package/adapters/mcp/toolset-names.ts +5 -0
  71. package/adapters/mcp/toolset.ts +6 -5
  72. package/adapters/mcp/transports/http-observation.ts +365 -0
  73. package/adapters/mcp/transports/http.ts +154 -677
  74. package/adapters/mcp/transports/oauth-http.ts +322 -0
  75. package/adapters/mcp/transports/session-registry.ts +6 -0
  76. package/adapters/mcp/tunnels/openai-secure-tunnel.ts +89 -5
  77. package/assets/plugin-registry.v1.json +6 -4
  78. package/assets/reference-configs/agentic-development-flow.md +25 -0
  79. package/assets/reference-configs/global-working-rules.md +19 -0
  80. package/assets/skill-version.json +2 -2
  81. package/docs/architecture/CURRENT.md +111 -41
  82. package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +14 -5
  83. package/docs/architecture/decisions/20260823-immediate-controller-relay.md +6 -3
  84. package/docs/architecture/decisions/20260907-assistant-learning-loop.md +2 -0
  85. package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +19 -4
  86. package/docs/architecture/decisions/20260916-workflow-supervisor-authority.md +249 -0
  87. package/docs/architecture/decisions/20260917-cognitive-memory-foundation.md +82 -0
  88. package/docs/architecture/decisions/20260918-stable-candidate-release-lifecycle.md +221 -0
  89. package/docs/architecture/decisions/20260919-autonomous-work-liveness.md +62 -0
  90. package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +72 -0
  91. package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +237 -0
  92. package/docs/architecture/decisions/20261005-forge-v3-desktop-client-boundary.md +77 -0
  93. package/docs/architecture/domains/verification.md +1 -0
  94. package/docs/architecture/domains/workflow-engine.md +6 -0
  95. package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +1 -1
  96. package/docs/forge-plugin-management.md +2 -2
  97. package/docs/operations/controller-performance-and-502.md +17 -0
  98. package/docs/operations/controller-reliability-runbook.md +2 -2
  99. package/docs/operations/features.md +1 -1
  100. package/docs/operations/features.zh-CN.md +1 -1
  101. package/docs/operations/homebrew.md +2 -2
  102. package/docs/operations/mcp-tool-exposure.md +2 -0
  103. package/docs/operations/releasing.md +2 -0
  104. package/docs/operations/standalone-disaster-recovery.md +14 -6
  105. package/docs/wiki/Implementation.md +1 -1
  106. package/package.json +25 -14
  107. package/packages/kernel/cognition/api/index.ts +6 -0
  108. package/packages/kernel/cognition/application/activation-service.ts +451 -0
  109. package/packages/kernel/cognition/application/consolidation-service.ts +185 -0
  110. package/packages/kernel/cognition/application/legacy-experience-adapter.ts +38 -0
  111. package/packages/kernel/cognition/application/memory-service.ts +64 -0
  112. package/packages/kernel/cognition/domain/learning.ts +106 -0
  113. package/packages/kernel/cognition/domain/memory.ts +254 -0
  114. package/packages/kernel/controller/api/index.ts +1 -0
  115. package/packages/kernel/controller/application/continuation-service.ts +281 -0
  116. package/packages/kernel/controller/application/controller-round-service.ts +12 -0
  117. package/packages/kernel/controller/domain/controller-round-transition-policy.ts +242 -21
  118. package/packages/kernel/controller/domain/controller-round.ts +4 -1
  119. package/packages/kernel/controller/domain/execution-quality.ts +3 -1
  120. package/packages/kernel/controller/infrastructure/controller-round-store.ts +689 -103
  121. package/packages/kernel/controller/infrastructure/controller-session-store.ts +297 -71
  122. package/packages/kernel/controller/ports/controller-host.ts +2 -0
  123. package/packages/kernel/identity/api/index.ts +10 -0
  124. package/packages/kernel/identity/domain/activity-projection.ts +43 -0
  125. package/packages/kernel/identity/domain/capability-broker.ts +60 -0
  126. package/packages/kernel/identity/domain/grant.ts +72 -0
  127. package/packages/kernel/identity/domain/owned-resource.ts +116 -0
  128. package/packages/kernel/identity/domain/user-request.ts +93 -0
  129. package/packages/kernel/identity/infrastructure/activity-projection-store.ts +77 -0
  130. package/packages/kernel/identity/infrastructure/capability-broker.ts +81 -0
  131. package/packages/kernel/identity/infrastructure/grant-store.ts +284 -0
  132. package/packages/kernel/identity/infrastructure/owned-resource-store.ts +259 -0
  133. package/packages/kernel/identity/infrastructure/user-request-store.ts +182 -0
  134. package/packages/kernel/scheduler/api/index.ts +0 -2
  135. package/packages/kernel/scheduler/application/schedule-service.ts +3 -0
  136. package/packages/kernel/scheduler/application/settlement.ts +0 -15
  137. package/packages/kernel/scheduler/domain/schedule.ts +87 -0
  138. package/packages/kernel/scheduler/infrastructure/schedule-store.ts +153 -133
  139. package/packages/kernel/work/api/index.ts +3 -2
  140. package/packages/kernel/work/application/work-service.ts +17 -42
  141. package/packages/kernel/work/domain/current-task-lineage.ts +104 -0
  142. package/packages/kernel/work/domain/engineering-design.ts +10 -5
  143. package/packages/kernel/work/domain/engineering-profile.ts +8 -12
  144. package/packages/kernel/work/domain/evaluation-promotion-receipt.ts +186 -0
  145. package/packages/kernel/work/domain/execution-concurrency.ts +19 -26
  146. package/packages/kernel/work/domain/execution-snapshot.ts +0 -31
  147. package/packages/kernel/work/domain/implementation-review.ts +14 -331
  148. package/packages/kernel/work/domain/objective-graph.ts +119 -0
  149. package/packages/kernel/work/domain/project-engineering-contract.ts +23 -1
  150. package/packages/kernel/work/domain/repository-completion-receipt.ts +1 -1
  151. package/packages/kernel/work/domain/state-machine.ts +25 -63
  152. package/packages/kernel/work/domain/types.ts +57 -51
  153. package/packages/kernel/work/infrastructure/work-contract-store.ts +819 -728
  154. package/packages/kernel/work/ports/work-contract-store.ts +5 -2
  155. package/packages/plugin-runtime/browser/session-authority.ts +2 -1
  156. package/packages/plugin-runtime/computer/chatgpt-identity.ts +24 -0
  157. package/packages/plugin-runtime/computer/conversation-target.ts +143 -0
  158. package/packages/plugin-runtime/computer/index.ts +2 -0
  159. package/packages/plugin-runtime/computer/target-authority.ts +26 -1
  160. package/packages/plugin-runtime/external/unix-jsonl-transport.ts +142 -18
  161. package/packages/protocols/computer/contract.ts +27 -1
  162. package/scripts/activate-source-baseline.ts +7 -9
  163. package/scripts/canary-controller-semantic-wait.ts +12 -24
  164. package/scripts/check-mcp-compatibility.ts +48 -136
  165. package/scripts/check-runtime-architecture.mjs +622 -217
  166. package/scripts/forge-local-recovery-helper.mjs +93 -15
  167. package/scripts/lib/project-init-lib.sh +3 -0
  168. package/scripts/open-source-audit-allowlist.txt +1 -2
  169. package/scripts/run-bounded-command.mjs +5 -0
  170. package/scripts/run-governed-gate.ts +0 -1
  171. package/scripts/run-mobile-monitor-bridge.ts +0 -1
  172. package/scripts/smoke-control-plane-failure-domain.ts +94 -0
  173. package/scripts/smoke-mcp-http-runtime.ts +5 -0
  174. package/scripts/smoke-runtime-recovery.ts +12 -43
  175. package/scripts/smoke-schedule-engine.ts +23 -15
  176. package/scripts/smoke-unattended-transport-recovery.ts +223 -0
  177. package/scripts/smoke-user-request-continuation-restart.ts +232 -0
  178. package/scripts/smoke-workflow-supervisor-chrome-adapter.ts +92 -0
  179. package/scripts/smoke-workflow-supervisor-process-restart.ts +276 -0
  180. package/scripts/smoke-workflow-supervisor-restart-recovery.ts +150 -0
  181. package/scripts/smoke-workflow-supervisor.ts +103 -0
  182. package/scripts/verify-forge-runtime.sh +2 -1
  183. package/src/cli/agent-jobs/executor-health.ts +11 -34
  184. package/src/cli/agent-jobs/integration.ts +18 -49
  185. package/src/cli/agent-jobs/job-manager.ts +7 -3
  186. package/src/cli/commands/brain-assistant.ts +27 -13
  187. package/src/cli/commands/brain.ts +13 -15
  188. package/src/cli/commands/chatgpt.ts +1 -163
  189. package/src/cli/commands/recovery.ts +135 -121
  190. package/src/cli/commands/runtime.ts +3 -3
  191. package/src/cli/commands/setup-profile.ts +8 -0
  192. package/src/cli/controller/check-runner.ts +13 -2
  193. package/src/cli/controller/completion-backlog.ts +3 -3
  194. package/src/cli/controller/completion-orchestrator.ts +4 -43
  195. package/src/cli/controller/completion-target.ts +3 -72
  196. package/src/cli/controller/context/source-materializer.ts +81 -100
  197. package/src/cli/controller/context-pack.ts +10 -8
  198. package/src/cli/controller/execution-completion.ts +4 -7
  199. package/src/cli/controller/execution-policy.ts +36 -153
  200. package/src/cli/controller/governance.ts +2 -3
  201. package/src/cli/controller/issue-store.ts +4 -99
  202. package/src/cli/controller/launch-agents.ts +59 -18
  203. package/src/cli/controller/operational-plan.ts +24 -51
  204. package/src/cli/controller/runtime-config.ts +5 -1
  205. package/src/cli/controller/stuck-state-migration.ts +2 -3
  206. package/src/cli/controller/systemd-user.ts +39 -1
  207. package/src/cli/editing/edit-session.ts +1 -7
  208. package/src/cli/local-bridge/console-automations.ts +18 -13
  209. package/src/cli/local-bridge/console-view-models.ts +3 -12
  210. package/src/cli/local-bridge/facade-api.ts +64 -191
  211. package/src/cli/local-bridge/server.ts +24 -147
  212. package/src/cli/local-bridge/types.ts +0 -1
  213. package/src/cli/mcp/oauth-client-retirement.ts +74 -0
  214. package/src/cli/repositories/command-executor.ts +29 -23
  215. package/src/cli/repositories/command-scope.ts +35 -16
  216. package/src/cli/repositories/controller-home.ts +48 -0
  217. package/src/cli/repositories/ephemeral-workspace.ts +20 -30
  218. package/src/cli/repositories/git-command-executor.ts +2 -2
  219. package/src/cli/repositories/registry.ts +77 -11
  220. package/src/cli/repositories/structured-git.ts +62 -2
  221. package/src/cli/repository/session-cache.ts +92 -6
  222. package/src/runtime/context/assistant-context.ts +20 -7
  223. package/src/runtime/context/assistant-work-context.ts +89 -27
  224. package/src/runtime/context/automatic-learning.ts +565 -0
  225. package/src/runtime/context/cognitive-attention.ts +173 -0
  226. package/src/runtime/context/cognitive-skill-canary.ts +158 -0
  227. package/src/runtime/context/context-closure.ts +46 -9
  228. package/src/runtime/context/context-pack-process.ts +103 -0
  229. package/src/runtime/context/context-plane.ts +1 -9
  230. package/src/runtime/context/direct-controller-learning.ts +298 -0
  231. package/src/runtime/context/semantic-navigation-contract.ts +9 -0
  232. package/src/runtime/context/semantic-navigation.ts +6 -34
  233. package/src/runtime/context/typescript-navigation-process.ts +145 -0
  234. package/src/runtime/context/typescript-navigation.ts +89 -3
  235. package/src/runtime/control-plane/cleanup-artifact-retention.ts +212 -9
  236. package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +9 -47
  237. package/src/runtime/control-plane/execution/controller-authority-recovery.ts +34 -4
  238. package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +29 -20
  239. package/src/runtime/control-plane/execution/execution-identity.ts +23 -3
  240. package/src/runtime/control-plane/execution/repository-work-attribution.ts +7 -30
  241. package/src/runtime/control-plane/execution/retained-work-resume.ts +206 -199
  242. package/src/runtime/control-plane/execution/session-store.ts +31 -1
  243. package/src/runtime/control-plane/execution/validation.ts +6 -8
  244. package/src/runtime/control-plane/execution/work-authority-reconciler.ts +13 -42
  245. package/src/runtime/control-plane/execution/work-check-evidence.ts +137 -0
  246. package/src/runtime/control-plane/execution/work-completion-authority.ts +30 -85
  247. package/src/runtime/control-plane/execution/work-delivery-service.ts +497 -0
  248. package/src/runtime/control-plane/execution/work-evidence-policy.ts +12 -50
  249. package/src/runtime/control-plane/execution/work-execution-support.ts +50 -149
  250. package/src/runtime/control-plane/execution/work-handle-authority.ts +188 -109
  251. package/src/runtime/control-plane/execution/work-handle-store.ts +19 -43
  252. package/src/runtime/control-plane/execution/work-head-settlement.ts +53 -20
  253. package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +52 -29
  254. package/src/runtime/control-plane/execution/work-operation-service.ts +43 -27
  255. package/src/runtime/control-plane/execution/work-preparation-service.ts +126 -266
  256. package/src/runtime/control-plane/execution/work-remote-delivery.ts +2 -3
  257. package/src/runtime/control-plane/execution/work-revision-diff.ts +39 -0
  258. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +173 -186
  259. package/src/runtime/control-plane/execution/work-validation-reconciler.ts +28 -84
  260. package/src/runtime/control-plane/execution/work-verification-service.ts +406 -50
  261. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +5 -1
  262. package/src/runtime/control-plane/facade/capability-registry.ts +362 -37
  263. package/src/runtime/control-plane/facade/check-normalization.ts +3 -9
  264. package/src/runtime/control-plane/facade/codex-delegation.ts +10 -11
  265. package/src/runtime/control-plane/facade/controller-connection.ts +135 -0
  266. package/src/runtime/control-plane/facade/goal-workloop-access.ts +1 -20
  267. package/src/runtime/control-plane/facade/goal-workloop.ts +281 -1753
  268. package/src/runtime/control-plane/facade/handoff-inbox-application.ts +12 -25
  269. package/src/runtime/control-plane/facade/handoff-inbox-store.ts +256 -52
  270. package/src/runtime/control-plane/facade/index.ts +0 -1
  271. package/src/runtime/control-plane/facade/operation-digest.ts +12 -15
  272. package/src/runtime/control-plane/facade/plan-contract-store.ts +451 -991
  273. package/src/runtime/control-plane/facade/policy-gate.ts +0 -23
  274. package/src/runtime/control-plane/facade/repository-work-admission.ts +12 -22
  275. package/src/runtime/control-plane/facade/requirement-authority.ts +102 -199
  276. package/src/runtime/control-plane/facade/requirement-board.ts +3 -3
  277. package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +51 -14
  278. package/src/runtime/control-plane/facade/self-healing-loop.ts +18 -53
  279. package/src/runtime/control-plane/facade/suggested-actions.ts +15 -18
  280. package/src/runtime/control-plane/facade/types.ts +49 -108
  281. package/src/runtime/control-plane/facade/work-continuation.ts +8 -8
  282. package/src/runtime/control-plane/generated-cache-retention.ts +97 -1
  283. package/src/runtime/control-plane/global-scheduler/autonomous-continuation.ts +248 -0
  284. package/src/runtime/control-plane/global-scheduler/durable-admission.ts +1 -1
  285. package/src/runtime/control-plane/global-scheduler/maintenance.ts +239 -112
  286. package/src/runtime/control-plane/global-scheduler/reconciliation.ts +2 -1
  287. package/src/runtime/control-plane/global-scheduler/scheduler.ts +66 -40
  288. package/src/runtime/control-plane/global-scheduler/wake-signal.ts +42 -2
  289. package/src/runtime/control-plane/governance/access-policy.ts +19 -2
  290. package/src/runtime/control-plane/governance/authorization.ts +20 -3
  291. package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +63 -300
  292. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +28 -300
  293. package/src/runtime/control-plane/launcher/local-conversation-controller.ts +238 -0
  294. package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +5 -2
  295. package/src/runtime/control-plane/launcher/thin-launcher.ts +96 -240
  296. package/src/runtime/control-plane/persistence/cognition-store.ts +820 -0
  297. package/src/runtime/control-plane/persistence/experience-store.ts +162 -29
  298. package/src/runtime/control-plane/persistence/requirement-store.ts +216 -74
  299. package/src/runtime/control-plane/persistence/sqlite-store.ts +113 -6
  300. package/src/runtime/control-plane/release-retention.ts +135 -47
  301. package/src/runtime/control-plane/repository-namespace-retention.ts +2 -2
  302. package/src/runtime/control-plane/runtime-cleanup.ts +290 -21
  303. package/src/runtime/control-plane/workspace/project-onboarding.ts +80 -0
  304. package/src/runtime/control-plane/workspace/semantic-sync-service.ts +19 -5
  305. package/src/runtime/control-plane/workspace/workspace-store.ts +169 -0
  306. package/src/runtime/diagnostics/incident-repair.ts +313 -146
  307. package/src/runtime/diagnostics/mcp-timing.ts +114 -0
  308. package/src/runtime/evidence/artifact-store.ts +158 -40
  309. package/src/runtime/evidence/evidence-store.ts +112 -8
  310. package/src/runtime/evidence/output-handle-index.ts +225 -0
  311. package/src/runtime/evidence/result-store.ts +158 -44
  312. package/src/runtime/execution/jobs/store.ts +3 -4
  313. package/src/runtime/execution/managed-workspace.ts +57 -0
  314. package/src/runtime/execution/process-runtime/check-facade.ts +1 -1
  315. package/src/runtime/execution/process-runtime/check-result-retention.ts +2 -2
  316. package/src/runtime/execution/process-runtime/check-result.ts +105 -1
  317. package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +18 -8
  318. package/src/runtime/execution/process-runtime/command-facade.ts +79 -27
  319. package/src/runtime/execution/process-runtime/gc.ts +15 -2
  320. package/src/runtime/execution/process-runtime/handle-index.ts +176 -0
  321. package/src/runtime/execution/process-runtime/host-command-lane.ts +139 -0
  322. package/src/runtime/execution/process-runtime/index.ts +3 -0
  323. package/src/runtime/execution/process-runtime/lightweight-managed.ts +251 -72
  324. package/src/runtime/execution/process-runtime/persisted-check.ts +3 -3
  325. package/src/runtime/execution/process-runtime/process-runner-entry.ts +47 -5
  326. package/src/runtime/execution/process-runtime/process-scope.ts +160 -0
  327. package/src/runtime/execution/process-runtime/resource-claims.ts +65 -61
  328. package/src/runtime/execution/process-runtime/runtime.ts +35 -2
  329. package/src/runtime/execution/process-runtime/store.ts +30 -2
  330. package/src/runtime/execution/process-runtime/types.ts +6 -1
  331. package/src/runtime/execution/workers/executor.ts +2 -6
  332. package/src/runtime/platform/service-inventory.ts +130 -0
  333. package/src/runtime/platform/service-manager.ts +8 -0
  334. package/src/runtime/plugins/action-application.ts +85 -28
  335. package/src/runtime/plugins/app-store-connect-adapter.ts +38 -14
  336. package/src/runtime/plugins/browser-adapter.ts +757 -34
  337. package/src/runtime/plugins/browser-automation-service.ts +23 -3
  338. package/src/runtime/plugins/browser-macos-bridge.ts +321 -29
  339. package/src/runtime/plugins/browser-manifest-surface.ts +45 -11
  340. package/src/runtime/plugins/browser-native-session-service.ts +63 -13
  341. package/src/runtime/plugins/browser-registration.ts +16 -0
  342. package/src/runtime/plugins/browser-runtime.ts +14 -1
  343. package/src/runtime/plugins/browser-session-authority.ts +2 -2
  344. package/src/runtime/plugins/browser-session-store.ts +46 -76
  345. package/src/runtime/plugins/capability-authorization-grants.ts +258 -62
  346. package/src/runtime/plugins/computer-chatgpt-browser-adapter-installer.ts +219 -0
  347. package/src/runtime/plugins/computer-chatgpt-macos-target.ts +891 -0
  348. package/src/runtime/plugins/computer-registration.ts +222 -11
  349. package/src/runtime/plugins/desktop-operator-external-policy.ts +36 -4
  350. package/src/runtime/plugins/desktop-operator-registration.ts +12 -4
  351. package/src/runtime/plugins/external-adapter.ts +42 -6
  352. package/src/runtime/plugins/external-registration.ts +21 -1
  353. package/src/runtime/plugins/gmail-adapter.ts +23 -2
  354. package/src/runtime/plugins/google-calendar-adapter.ts +2 -2
  355. package/src/runtime/plugins/google-shared.ts +14 -7
  356. package/src/runtime/plugins/google-tasks-adapter.ts +2 -2
  357. package/src/runtime/plugins/ios-adapter.ts +1 -1
  358. package/src/runtime/plugins/lightweight-action.ts +208 -2
  359. package/src/runtime/plugins/local-system-adapter.ts +12 -2
  360. package/src/runtime/plugins/managed-process-adapter.ts +12 -5
  361. package/src/runtime/plugins/plugin-action-sidecar.ts +17 -13
  362. package/src/runtime/plugins/plugin-management-adapter.ts +1 -1
  363. package/src/runtime/plugins/store.ts +602 -428
  364. package/src/runtime/plugins/types.ts +20 -0
  365. package/src/runtime/plugins/xiaohongshu-publish.ts +16 -0
  366. package/src/runtime/projections/invalidation.ts +7 -3
  367. package/src/runtime/projections/materialized-view.ts +80 -36
  368. package/src/runtime/recovery/actions.ts +3 -3
  369. package/src/runtime/recovery/capability-action-application.ts +46 -45
  370. package/src/runtime/recovery/lifecycle-inventory.ts +29 -29
  371. package/src/runtime/recovery/maintenance-executor.ts +374 -123
  372. package/src/runtime/recovery/store.ts +29 -11
  373. package/src/runtime/release/release-coordinator.ts +296 -0
  374. package/src/runtime/release/release-session.ts +716 -0
  375. package/src/runtime/release/release-state-migration.ts +25 -0
  376. package/src/runtime/resources/leases/store.ts +56 -25
  377. package/src/runtime/root/computer-composition.ts +191 -6
  378. package/src/runtime/root/controller-progression-composition.ts +192 -0
  379. package/src/runtime/root/controller-round-composition.ts +20 -1
  380. package/src/runtime/root/deployment-topology.ts +106 -0
  381. package/src/runtime/root/entry.ts +4 -3
  382. package/src/runtime/root/known-good-recovery.ts +184 -0
  383. package/src/runtime/root/local-bridge.ts +0 -1
  384. package/src/runtime/root/mcp-transport.ts +111 -18
  385. package/src/runtime/root/ownership.ts +261 -9
  386. package/src/runtime/root/package-connector-service.ts +105 -19
  387. package/src/runtime/root/package-runtime-release.ts +117 -18
  388. package/src/runtime/root/package-runtime-service.ts +17 -11
  389. package/src/runtime/root/release-execution-canary.ts +44 -12
  390. package/src/runtime/root/release-loader.ts +90 -8
  391. package/src/runtime/root/release-manifest.ts +80 -6
  392. package/src/runtime/root/release-materialize.ts +372 -28
  393. package/src/runtime/root/release-store.ts +395 -36
  394. package/src/runtime/root/runtime-lane.ts +191 -0
  395. package/src/runtime/root/runtime.ts +159 -27
  396. package/src/runtime/root/scheduled-controller-composition.ts +28 -3
  397. package/src/runtime/root/service-runner.ts +2 -2
  398. package/src/runtime/root/service.ts +36 -33
  399. package/src/runtime/root/status.ts +48 -0
  400. package/src/runtime/root/types.ts +32 -3
  401. package/src/runtime/root/workflow-supervisor-composition.ts +493 -0
  402. package/src/runtime/root/workflow-supervisor-runtime.ts +209 -0
  403. package/src/runtime/root/write-fence.ts +50 -2
  404. package/src/runtime/safe-tooling/google-credential-store.ts +76 -21
  405. package/src/runtime/safe-tooling/google-oauth-broker.ts +25 -7
  406. package/src/runtime/safe-tooling/workspace-auth.ts +1 -1
  407. package/src/runtime/shared/bounded-child-supervisor.ts +9 -1
  408. package/src/runtime/shared/process-environment.ts +20 -9
  409. package/src/runtime/shared/response-budget.ts +1 -3
  410. package/src/runtime/standalone-recovery/controller-home-migration.ts +16 -24
  411. package/src/runtime/standalone-recovery/core.ts +3702 -342
  412. package/src/runtime/standalone-recovery/entry.ts +469 -39
  413. package/src/runtime/standalone-recovery/installer.ts +262 -148
  414. package/src/runtime/standalone-recovery/mcp-server.ts +29 -193
  415. package/src/runtime/standalone-recovery/operation-lock.ts +1 -1
  416. package/src/runtime/standalone-recovery/performance.ts +54 -16
  417. package/src/runtime/standalone-recovery/release.ts +53 -5
  418. package/src/runtime/standalone-recovery/service-labels.ts +5 -2
  419. package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +5 -2
  420. package/src/runtime/workflow/schedules/browser-probe.ts +17 -6
  421. package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +10 -3
  422. package/src/runtime/workflow/schedules/engine.ts +138 -172
  423. package/src/runtime/workflow/schedules/work-continuation.ts +44 -5
  424. package/src/runtime/workflows/runtime.ts +15 -19
  425. package/src/testing/test-governance.ts +5 -1
  426. package/supervisor/chatgpt-conversation.ts +23 -0
  427. package/supervisor/client.ts +201 -0
  428. package/supervisor/control-plane.ts +868 -0
  429. package/supervisor/entry.ts +15 -0
  430. package/supervisor/forge-validators.ts +80 -0
  431. package/supervisor/index.ts +5 -0
  432. package/supervisor/native-browser-adapter.ts +786 -0
  433. package/supervisor/native-messaging/host.ts +39 -0
  434. package/supervisor/native-messaging/manifest.ts +26 -0
  435. package/supervisor/native-messaging/protocol.ts +27 -0
  436. package/supervisor/paths.ts +18 -0
  437. package/supervisor/protocol.ts +202 -0
  438. package/supervisor/server.ts +404 -0
  439. package/supervisor/store.ts +1451 -0
  440. package/supervisor/tsconfig.json +8 -0
  441. package/supervisor/types.ts +255 -0
  442. package/adapters/chatgpt/controller-host.ts +0 -119
  443. package/adapters/mcp/controller-round-compatibility.ts +0 -184
  444. package/adapters/mcp/frozen-client-semantic-compatibility.ts +0 -292
  445. package/adapters/mcp/runtime-gateway/work-compat-adapter.ts +0 -502
  446. package/packages/kernel/progression/api/index.ts +0 -2
  447. package/packages/kernel/progression/application/projector.ts +0 -211
  448. package/packages/kernel/progression/domain/types.ts +0 -116
  449. package/packages/kernel/progression/index.ts +0 -1
  450. package/packages/kernel/scheduler/application/continuation-service.ts +0 -212
  451. package/packages/kernel/scheduler/domain/continuation.ts +0 -38
  452. package/packages/kernel/scheduler/infrastructure/continuation-dispatch-store.ts +0 -38
  453. package/packages/kernel/work/domain/admission-policy.ts +0 -34
  454. package/scripts/benchmark-background-check-overlap.ts +0 -228
  455. package/scripts/benchmark-computer-hotpath.ts +0 -255
  456. package/scripts/benchmark-controller-hotpath.ts +0 -212
  457. package/scripts/benchmark-controller-round2.ts +0 -191
  458. package/scripts/benchmark-ios-agent-device.ts +0 -511
  459. package/scripts/benchmark-mcp-host.sh +0 -117
  460. package/scripts/benchmark-mcp-transport.ts +0 -169
  461. package/scripts/benchmark-operational-memory-activation.ts +0 -235
  462. package/scripts/benchmark-operational-shadow.ts +0 -28
  463. package/scripts/benchmark-quality-harness.ts +0 -146
  464. package/scripts/benchmark-route-session-concurrency.ts +0 -915
  465. package/scripts/benchmark-thin-harness-gateway-ab.ts +0 -632
  466. package/scripts/benchmark-thin-harness-mcp-e2e.ts +0 -498
  467. package/scripts/benchmark-thin-harness.ts +0 -251
  468. package/scripts/benchmark-typescript-navigation.ts +0 -186
  469. package/scripts/benchmark-work-efficiency.ts +0 -334
  470. package/scripts/build-controller-ui.ts +0 -28
  471. package/scripts/check-npm-release.sh +0 -32
  472. package/scripts/check-public-release-surface.sh +0 -19
  473. package/scripts/check-release-published.sh +0 -57
  474. package/scripts/check-release-readiness.sh +0 -37
  475. package/scripts/check-release-version.mjs +0 -74
  476. package/scripts/check-tarball-install-smoke.sh +0 -150
  477. package/scripts/package-source-archive.sh +0 -147
  478. package/scripts/public-release-files.txt +0 -39
  479. package/scripts/public-release.ts +0 -174
  480. package/scripts/publish-release-tarball.sh +0 -27
  481. package/scripts/route-nl-vs-ts-eval.ts +0 -679
  482. package/scripts/stage-runtime-release.ts +0 -44
  483. package/src/cli/controller/progress.ts +0 -656
  484. package/src/cli/controller/work-mode.ts +0 -181
  485. package/src/cli/local-bridge/console-assets.ts +0 -17
  486. package/src/cli/local-bridge/dashboard.ts +0 -17
  487. package/src/cli/local-bridge/frontend/src/App.tsx +0 -10
  488. package/src/cli/local-bridge/frontend/src/components/Button.tsx +0 -1
  489. package/src/cli/local-bridge/frontend/src/components/DetailPane.tsx +0 -3
  490. package/src/cli/local-bridge/frontend/src/components/SearchField.tsx +0 -1
  491. package/src/cli/local-bridge/frontend/src/components/SectionHeader.tsx +0 -1
  492. package/src/cli/local-bridge/frontend/src/components/Segmented.tsx +0 -1
  493. package/src/cli/local-bridge/frontend/src/components/StatusText.tsx +0 -3
  494. package/src/cli/local-bridge/frontend/src/design/icons.tsx +0 -11
  495. package/src/cli/local-bridge/frontend/src/design/tokens.css +0 -8
  496. package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +0 -153
  497. package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +0 -37
  498. package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +0 -183
  499. package/src/cli/local-bridge/frontend/src/features/repositories/RepositoriesView.tsx +0 -2
  500. package/src/cli/local-bridge/frontend/src/features/system/SystemView.tsx +0 -2
  501. package/src/cli/local-bridge/frontend/src/features/work/WorkView.tsx +0 -4
  502. package/src/cli/local-bridge/frontend/src/lib/api.ts +0 -30
  503. package/src/cli/local-bridge/frontend/src/lib/format.ts +0 -4
  504. package/src/cli/local-bridge/frontend/src/lib/routes.ts +0 -7
  505. package/src/cli/local-bridge/frontend/src/main.tsx +0 -1
  506. package/src/cli/local-bridge/frontend/src/shell/AppShell.tsx +0 -1
  507. package/src/cli/local-bridge/frontend/src/shell/CommandBar.tsx +0 -2
  508. package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +0 -4
  509. package/src/cli/local-bridge/frontend/src/styles.css +0 -28
  510. package/src/cli/local-bridge/frontend/src/types.ts +0 -15
  511. package/src/cli/local-bridge/frontend/src/vite-env.d.ts +0 -1
  512. package/src/cli/local-bridge/frontend/vite.config.ts +0 -27
  513. package/src/cli/local-bridge/ui-dist/app.css +0 -1
  514. package/src/cli/local-bridge/ui-dist/app.js +0 -11228
  515. package/src/runtime/control-plane/execution/content-equivalent-commit-authority.ts +0 -169
  516. package/src/runtime/control-plane/execution/direct-canonical-work-reconciliation.ts +0 -85
  517. package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +0 -655
  518. package/src/runtime/control-plane/execution/work-finalization-service.ts +0 -2850
  519. package/src/runtime/control-plane/execution/work-path-scope.ts +0 -37
  520. package/src/runtime/control-plane/execution/work-task-receipt.ts +0 -468
  521. package/src/runtime/control-plane/facade/controller-round-relay.ts +0 -3
  522. package/src/runtime/control-plane/facade/work-admission-policy.ts +0 -142
  523. package/src/runtime/control-plane/facade/work-implementation-review.ts +0 -2
  524. package/src/runtime/control-plane/facade/work-state-machine.ts +0 -2
  525. package/src/runtime/control-plane/facade/work-task-projection.ts +0 -66
  526. package/src/runtime/control-plane/routing/index.ts +0 -1
  527. package/src/runtime/control-plane/routing/route-policy.ts +0 -401
  528. package/src/runtime/control-plane/routing/workspace-admission.ts +0 -70
@@ -0,0 +1,145 @@
1
+ import type { CallToolResult } from '../../../packages/protocols/mcp/tool-contract';
2
+ import { getWorkContract } from '../../../packages/kernel/work/api/index';
3
+ import {
4
+ recordControllerExperience,
5
+ recordControllerOutcome,
6
+ type ControllerExperienceDraft,
7
+ type ControllerOutcomeObservationDraft,
8
+ } from '../../../src/runtime/context/assistant-work-context';
9
+ import { parseControllerLearningSignalDrafts } from '../../../src/runtime/context/automatic-learning';
10
+ import { persistDirectControllerLearning, recordDirectControllerLearningFeedback, type DirectControllerLearningFeedbackDraft } from '../../../src/runtime/context/direct-controller-learning';
11
+ import { buildFacadeResult } from '../../../src/runtime/control-plane/facade';
12
+ import type { MultiRepositoryMcpToolContext } from '../multi-repository';
13
+ import { result } from './result-adapter';
14
+
15
+ type RepositoryIdentity = { repoId: string; activeCheckoutId: string };
16
+
17
+ /**
18
+ * rh_work learning dispatch is advisory. Generic learning needs no Work; Work-specific
19
+ * outcome/experience writes are bound to exact Work provenance and canonical evidence.
20
+ * ControllerSession/ControllerRound state never grants write authority here.
21
+ */
22
+ export function callRhWorkLearningOperation(
23
+ ctx: MultiRepositoryMcpToolContext,
24
+ repository: RepositoryIdentity,
25
+ operation: string,
26
+ args: Record<string, unknown>,
27
+ ): CallToolResult | undefined {
28
+ if (!['learning_record', 'learning_feedback', 'outcome_record', 'experience_record'].includes(operation)) return undefined;
29
+ const store = { controllerHome: ctx.controllerHome, repoId: repository.repoId };
30
+ try {
31
+ if (operation === 'learning_feedback') {
32
+ if (!Array.isArray(args.learning_feedback) || args.learning_feedback.length === 0 || args.learning_feedback.length > 32) {
33
+ throw new Error('COGNITION_DIRECT_FEEDBACK_ITEMS_REQUIRED');
34
+ }
35
+ const feedback = args.learning_feedback.map((entry, index) => {
36
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) throw new Error(`COGNITION_DIRECT_FEEDBACK_ITEM_INVALID: ${index}`);
37
+ const item = entry as Record<string, unknown>;
38
+ const decision = String(item.decision ?? '').trim();
39
+ const memoryAddress = String(item.memory_address ?? '').trim();
40
+ const reason = String(item.reason ?? '').trim();
41
+ const rejectionKind = typeof item.rejection_kind === 'string' ? item.rejection_kind.trim() : undefined;
42
+ if (!memoryAddress || !['used', 'rejected'].includes(decision)) throw new Error(`COGNITION_DIRECT_FEEDBACK_ITEM_INVALID: ${index}`);
43
+ if (decision === 'rejected' && !['irrelevant', 'stale', 'contradicted'].includes(rejectionKind ?? '')) {
44
+ throw new Error(`COGNITION_DIRECT_FEEDBACK_REJECTION_KIND_REQUIRED: ${index}`);
45
+ }
46
+ if (decision === 'used' && rejectionKind) throw new Error(`COGNITION_DIRECT_FEEDBACK_REJECTION_KIND_UNEXPECTED: ${index}`);
47
+ return {
48
+ memoryAddress,
49
+ decision,
50
+ reason,
51
+ ...(rejectionKind ? { rejectionKind } : {}),
52
+ } as DirectControllerLearningFeedbackDraft;
53
+ });
54
+ const recorded = recordDirectControllerLearningFeedback({
55
+ controllerHome: ctx.controllerHome,
56
+ repository,
57
+ feedback,
58
+ principalId: ctx.principalId,
59
+ sessionId: ctx.sessionId,
60
+ controllerInstanceId: ctx.controllerInstanceId,
61
+ workId: typeof args.work_id === 'string' && args.work_id.trim() ? args.work_id.trim() : undefined,
62
+ });
63
+ return result(buildFacadeResult({
64
+ summary: `Recorded ${recorded.observationIds.length} lifecycle-free Cognitive usage feedback observation(s).`,
65
+ data: {
66
+ recorded: true,
67
+ observationIds: recorded.observationIds,
68
+ scopes: recorded.scopes,
69
+ authorityBoundary: 'Usage feedback adjusts advisory retrieval utility only; it grants no execution, lifecycle, or semantic authority.',
70
+ },
71
+ }) as unknown as Record<string, unknown>);
72
+ }
73
+
74
+ if (operation === 'learning_record') {
75
+ const signals = parseControllerLearningSignalDrafts(args.learning_signals);
76
+ if (signals.length === 0) throw new Error('COGNITION_DIRECT_LEARNING_SIGNALS_REQUIRED');
77
+ const learning = persistDirectControllerLearning({
78
+ controllerHome: ctx.controllerHome,
79
+ repository,
80
+ signals,
81
+ principalId: ctx.principalId,
82
+ sessionId: ctx.sessionId,
83
+ controllerInstanceId: ctx.controllerInstanceId,
84
+ controllerType: ctx.controllerType,
85
+ workId: typeof args.work_id === 'string' && args.work_id.trim() ? args.work_id.trim() : undefined,
86
+ });
87
+ return result(buildFacadeResult({
88
+ summary: `Recorded ${learning.storedMemoryIds.length} model-authored advisory learning item(s) without creating Work lifecycle.`,
89
+ data: {
90
+ recorded: true,
91
+ storedMemoryIds: learning.storedMemoryIds,
92
+ associatedEdgeCount: learning.associatedEdgeCount,
93
+ consolidatedMemoryIds: learning.consolidatedMemoryIds,
94
+ scopes: learning.scopes,
95
+ authorityBoundary: 'Cognitive advisory memory only; it never grants execution or lifecycle authority.',
96
+ },
97
+ }) as unknown as Record<string, unknown>);
98
+ }
99
+
100
+ const workId = String(args.work_id ?? '').trim();
101
+ if (!workId) throw new Error('LEARNING_LOOP_WORK_ID_REQUIRED');
102
+ const work = getWorkContract(store, workId);
103
+ if (!work) throw new Error(`WORK_NOT_FOUND: ${workId}`);
104
+ const identity = { workId };
105
+
106
+ if (operation === 'outcome_record') {
107
+ if (!args.outcome_observation || typeof args.outcome_observation !== 'object' || Array.isArray(args.outcome_observation)) {
108
+ throw new Error('OUTCOME_OBSERVATION_REQUIRED');
109
+ }
110
+ const outcome = recordControllerOutcome({
111
+ controllerHome: ctx.controllerHome,
112
+ repoId: repository.repoId,
113
+ identity,
114
+ draft: args.outcome_observation as ControllerOutcomeObservationDraft,
115
+ });
116
+ return result(buildFacadeResult({
117
+ summary: `OutcomeObservation ${outcome.id} recorded from canonical Work evidence.`,
118
+ data: { outcome },
119
+ }) as unknown as Record<string, unknown>);
120
+ }
121
+
122
+ if (!args.experience_draft || typeof args.experience_draft !== 'object' || Array.isArray(args.experience_draft)) {
123
+ throw new Error('EXPERIENCE_DRAFT_REQUIRED');
124
+ }
125
+ const experience = recordControllerExperience({
126
+ controllerHome: ctx.controllerHome,
127
+ repoId: repository.repoId,
128
+ identity,
129
+ draft: args.experience_draft as ControllerExperienceDraft,
130
+ qualityAdjustmentFingerprint: typeof args.quality_adjustment_fingerprint === 'string'
131
+ ? args.quality_adjustment_fingerprint.trim() || undefined
132
+ : undefined,
133
+ });
134
+ return result(buildFacadeResult({
135
+ summary: `Experience ${experience.id} recorded from canonical Work evidence for later advisory reuse.`,
136
+ data: { experience },
137
+ }) as unknown as Record<string, unknown>);
138
+ } catch (error) {
139
+ return result(buildFacadeResult({
140
+ status: 'blocked',
141
+ summary: error instanceof Error ? error.message : 'Learning record failed.',
142
+ data: { recorded: false },
143
+ }) as unknown as Record<string, unknown>, true);
144
+ }
145
+ }
@@ -0,0 +1,38 @@
1
+ import type { CallToolResult } from '../../../packages/protocols/mcp/tool-contract';
2
+ import {
3
+ listWorkContracts,
4
+ workSemanticView,
5
+ type WorkContractStoreOptions,
6
+ } from '../../../packages/kernel/work/api/index';
7
+ import { buildFacadeResult } from '../../../src/runtime/control-plane/facade';
8
+ import { result } from './result-adapter';
9
+
10
+ /**
11
+ * Bounded read-only collection projection for current and recent terminal semantic Work.
12
+ * Collection reads are separate from the semantic start/get/revise/complete
13
+ * mutation adapter so listing can never widen or gate semantic completion.
14
+ */
15
+ export function callRhWorkListProjection(
16
+ store: WorkContractStoreOptions,
17
+ operation: string,
18
+ args: Record<string, unknown>,
19
+ ): CallToolResult | undefined {
20
+ if (operation !== 'list') return undefined;
21
+ const limit = Math.max(1, Math.min(Math.trunc(typeof args.limit === 'number' ? args.limit : 50), 100));
22
+ const historyLimit = Math.min(limit, 50);
23
+ const works = listWorkContracts({ ...store, state: 'active', limit });
24
+ const recentHistory = [
25
+ ...listWorkContracts({ ...store, state: 'completed', limit: historyLimit }),
26
+ ...listWorkContracts({ ...store, state: 'cancelled', limit: historyLimit }),
27
+ ]
28
+ .sort((left, right) => right.updatedAt.localeCompare(left.updatedAt))
29
+ .slice(0, historyLimit);
30
+ return result(buildFacadeResult({
31
+ summary: `${works.length} current and ${recentHistory.length} recent terminal semantic Work(s) in this repository.`,
32
+ data: {
33
+ works: works.map(workSemanticView),
34
+ recentHistory: recentHistory.map(workSemanticView),
35
+ bounded: true,
36
+ },
37
+ }) as unknown as Record<string, unknown>);
38
+ }
@@ -0,0 +1,382 @@
1
+ import type { CallToolResult } from '../../../packages/protocols/mcp/tool-contract';
2
+ import type { MultiRepositoryMcpToolContext } from '../multi-repository';
3
+ import {
4
+ admitPlanContractAsync,
5
+ createPlanSemanticContext,
6
+ buildFacadeResult,
7
+ getPlanContract,
8
+ listPlanContracts,
9
+ normalizeCheckIds,
10
+ resolvePlanAdmission,
11
+ summarizePlanContract,
12
+ planSemanticView,
13
+ revisePlanSemanticContext,
14
+ listPlanSemanticRevisionRecords,
15
+ type CheckDefinitionLike,
16
+ type PlanContractStoreOptions,
17
+ } from '../../../src/runtime/control-plane/facade';
18
+ import { readRequirement } from '../../../src/runtime/control-plane/persistence/requirement-store';
19
+ import { listRepositories } from '../../../src/cli/repositories/registry';
20
+ import { SEMANTIC_SCOPE_KEY } from '../../../src/cli/repositories/controller-home';
21
+ import { result } from './result-adapter';
22
+
23
+ const RH_WORK_LIGHTWEIGHT_PLAN_OPERATIONS = new Set([
24
+ 'plan_list',
25
+ 'plan_get',
26
+ 'plan_revise',
27
+ ]);
28
+
29
+ export function isRhWorkLightweightPlanOperation(operation: string): boolean {
30
+ return RH_WORK_LIGHTWEIGHT_PLAN_OPERATIONS.has(operation);
31
+ }
32
+
33
+ export async function callRhWorkPlanOperation(
34
+ store: PlanContractStoreOptions,
35
+ operation: string,
36
+ args: Record<string, unknown>,
37
+ ): Promise<CallToolResult | undefined> {
38
+ if (!isRhWorkLightweightPlanOperation(operation)) return undefined;
39
+
40
+ if (operation === 'plan_list') {
41
+ const plans = listPlanContracts({ ...store, status: 'active', limit: typeof args.limit === 'number' ? args.limit : 20 });
42
+ const facade = buildFacadeResult({
43
+ summary: `${plans.length} current semantic Plan(s) in this repository.`,
44
+ data: { plans: plans.map(planSemanticView), bounded: true },
45
+ });
46
+ return result(facade as unknown as Record<string, unknown>);
47
+ }
48
+
49
+ if (operation === 'plan_get') {
50
+ const plan = getPlanContract(store, String(args.plan_id ?? ''));
51
+ const facade = plan
52
+ ? buildFacadeResult({
53
+ summary: `Plan ${plan.planId} current head retrieved at semantic revision ${planSemanticView(plan).revision}.`,
54
+ data: {
55
+ plan: planSemanticView(plan),
56
+ ...(args.detail_level === 'detail' ? { revisionHistory: listPlanSemanticRevisionRecords(store, plan.planId) } : {}),
57
+ },
58
+ detailLevel: args.detail_level === 'detail' ? 'detail' : 'summary',
59
+ })
60
+ : buildFacadeResult({
61
+ status: 'not_found',
62
+ summary: `PlanContract ${String(args.plan_id ?? '')} not found.`,
63
+ data: { planId: String(args.plan_id ?? '') },
64
+ });
65
+ return result(facade as unknown as Record<string, unknown>, !plan);
66
+ }
67
+
68
+ try {
69
+ if (operation === 'plan_revise') {
70
+ const planId = String(args.plan_id ?? '').trim();
71
+ const expectedRevision = Number(args.expected_revision);
72
+ const plan = revisePlanSemanticContext(store, planId, {
73
+ expectedRevision,
74
+ ...(typeof args.superseded_by === 'string' ? { supersededBy: args.superseded_by } : {}),
75
+ ...(typeof args.requirement_revision === 'number' ? { requirementBasisRevision: args.requirement_revision } : {}),
76
+ ...(typeof args.source_revision === 'string' ? { sourceBasisRevision: args.source_revision } : {}),
77
+ ...(typeof args.objective === 'string' ? { goal: args.objective } : {}),
78
+ ...(Array.isArray(args.non_goals) ? { nonGoals: args.non_goals.map(String) } : {}),
79
+ ...(Array.isArray(args.assumptions) ? { assumptions: args.assumptions.map(String) } : {}),
80
+ ...(Array.isArray(args.resolved_decisions) ? { resolvedDecisions: args.resolved_decisions.map(String) } : {}),
81
+ ...(Array.isArray(args.stop_conditions) ? { stopConditions: args.stop_conditions.map(String) } : {}),
82
+ ...(Array.isArray(args.replan_conditions) ? { replanConditions: args.replan_conditions.map(String) } : {}),
83
+ ...(args.integration_strategy === null || typeof args.integration_strategy === 'string' ? { integrationStrategy: args.integration_strategy as string | null } : {}),
84
+ ...(Array.isArray(args.plan_items) ? { items: args.plan_items
85
+ .filter((entry): entry is Record<string, unknown> => Boolean(entry) && typeof entry === 'object' && !Array.isArray(entry))
86
+ .map((entry) => ({
87
+ id: String(entry.id ?? ''),
88
+ objective: String(entry.objective ?? ''),
89
+ dependencies: Array.isArray(entry.dependencies) ? entry.dependencies.map(String) : [],
90
+ })) } : {}),
91
+ });
92
+ return result(buildFacadeResult({
93
+ summary: `Plan ${plan.planId} revised atomically to semantic revision ${planSemanticView(plan).revision}; source basis remains provenance metadata and no approval/execution transition was implied.`,
94
+ data: { plan: planSemanticView(plan), expectedRevision },
95
+ }) as unknown as Record<string, unknown>);
96
+ }
97
+
98
+ return undefined;
99
+ } catch (error) {
100
+ const currentPlanId = String(args.plan_id ?? '').trim();
101
+ const currentPlan = operation === 'plan_revise' && currentPlanId ? getPlanContract(store, currentPlanId) : undefined;
102
+ const facade = buildFacadeResult({
103
+ status: 'blocked',
104
+ summary: error instanceof Error ? error.message : 'PlanContract operation failed.',
105
+ data: {
106
+ operation,
107
+ executionStarted: false,
108
+ ...(currentPlan ? { currentPlan: planSemanticView(currentPlan) } : {}),
109
+ },
110
+ });
111
+ return result(facade as unknown as Record<string, unknown>, true);
112
+ }
113
+ }
114
+
115
+ function planObligationDispositionsFromArgs(value: unknown) {
116
+ if (!Array.isArray(value)) return undefined;
117
+ return value
118
+ .filter((entry): entry is Record<string, unknown> => Boolean(entry) && typeof entry === 'object' && !Array.isArray(entry))
119
+ .map((entry) => ({
120
+ predecessorPlanId: String(entry.predecessor_plan_id ?? ''),
121
+ obligationId: String(entry.obligation_id ?? ''),
122
+ disposition: String(entry.disposition ?? '') as 'keep' | 'change' | 'defer' | 'drop',
123
+ successorRefs: Array.isArray(entry.successor_refs) ? entry.successor_refs.map(String) : [],
124
+ rationale: typeof entry.rationale === 'string' ? entry.rationale : undefined,
125
+ }));
126
+ }
127
+
128
+ export interface RhWorkPlanCreateContext {
129
+ controllerHome: string;
130
+ /** Node-local placement provenance; absent when the Plan belongs to the ForgeInstance. */
131
+ repoId?: string;
132
+ checks: readonly CheckDefinitionLike[];
133
+ }
134
+
135
+ /**
136
+ * A Plan is authored semantic context: it can belong to the ForgeInstance with
137
+ * no repository and no source revision. When no repository target is available
138
+ * or explicitly requested, create it in the semantic scope; otherwise return
139
+ * undefined so the normal repository-bound path stays authoritative.
140
+ */
141
+ export async function callRhWorkPlanCreateWithoutRepository(
142
+ ctx: MultiRepositoryMcpToolContext,
143
+ operation: string,
144
+ args: Record<string, unknown>,
145
+ ): Promise<CallToolResult | undefined> {
146
+ if (operation !== 'plan_create') return undefined;
147
+ const explicitRepoId = typeof args.repo_id === 'string' ? args.repo_id.trim() : '';
148
+ if (explicitRepoId || ctx.explicitRepository) return undefined;
149
+ const enabled = listRepositories(ctx.controllerHome).filter((record) => record.enabled && !record.removedAt);
150
+ // Zero repositories means "ForgeInstance-scoped Plan". One means the sole
151
+ // repository stays authoritative; several keep the explicit disambiguation
152
+ // error instead of silently creating an unscoped Plan.
153
+ if (enabled.length !== 0) return undefined;
154
+ return callRhWorkPlanCreateOperation(
155
+ { controllerHome: ctx.controllerHome, scopeKey: SEMANTIC_SCOPE_KEY },
156
+ operation,
157
+ args,
158
+ { controllerHome: ctx.controllerHome, checks: [] },
159
+ );
160
+ }
161
+
162
+ export async function callRhWorkPlanCreateOperation(
163
+ store: PlanContractStoreOptions,
164
+ operation: string,
165
+ args: Record<string, unknown>,
166
+ context: RhWorkPlanCreateContext,
167
+ ): Promise<CallToolResult | undefined> {
168
+ if (operation !== 'plan_create') return undefined;
169
+
170
+ if (!Array.isArray(args.plan_steps)) {
171
+ try {
172
+ const plan = createPlanSemanticContext(store, {
173
+ planId: String(args.plan_id ?? ''),
174
+ repoId: context.repoId,
175
+ requirementId: typeof args.requirement_id === 'string' && args.requirement_id.trim() ? args.requirement_id.trim() : undefined,
176
+ requirementBasisRevision: typeof args.requirement_revision === 'number' ? args.requirement_revision : undefined,
177
+ scopeKey: typeof args.scope_key === 'string' ? args.scope_key : undefined,
178
+ sourceBasisRevision: typeof args.source_revision === 'string' ? args.source_revision : undefined,
179
+ goal: String(args.objective ?? ''),
180
+ nonGoals: Array.isArray(args.non_goals) ? args.non_goals.map(String) : undefined,
181
+ assumptions: Array.isArray(args.assumptions) ? args.assumptions.map(String) : undefined,
182
+ resolvedDecisions: Array.isArray(args.resolved_decisions) ? args.resolved_decisions.map(String) : undefined,
183
+ stopConditions: Array.isArray(args.stop_conditions) ? args.stop_conditions.map(String) : undefined,
184
+ replanConditions: Array.isArray(args.replan_conditions) ? args.replan_conditions.map(String) : undefined,
185
+ integrationStrategy: typeof args.integration_strategy === 'string' ? args.integration_strategy : undefined,
186
+ items: Array.isArray(args.plan_items)
187
+ ? args.plan_items
188
+ .filter((entry): entry is Record<string, unknown> => Boolean(entry) && typeof entry === 'object' && !Array.isArray(entry))
189
+ .map((entry) => ({
190
+ id: String(entry.id ?? ''),
191
+ objective: String(entry.objective ?? ''),
192
+ dependencies: Array.isArray(entry.dependencies) ? entry.dependencies.map(String) : [],
193
+ }))
194
+ : [],
195
+ });
196
+ return result(buildFacadeResult({
197
+ summary: `Plan ${plan.planId} created at semantic revision 1. Plan items are descriptive working memory; no approval, PlanStep, path/check, scheduling, Work, or acceptance authority was created.`,
198
+ data: { plan: planSemanticView(plan), planContractCreated: true, executionStarted: false },
199
+ }) as unknown as Record<string, unknown>);
200
+ } catch (error) {
201
+ return result(buildFacadeResult({
202
+ status: 'blocked',
203
+ summary: error instanceof Error ? error.message : 'Semantic Plan creation failed.',
204
+ data: { planContractCreated: false, executionStarted: false },
205
+ }) as unknown as Record<string, unknown>, true);
206
+ }
207
+ }
208
+
209
+ try {
210
+ // Frozen-client compatibility only. Current model-facing schema no longer exposes plan_steps.
211
+ const rawSteps = args.plan_steps;
212
+ const requestedPlanId = String(args.plan_id ?? '').trim();
213
+ const requestedRequirementId = typeof args.requirement_id === 'string' && args.requirement_id.trim() ? args.requirement_id.trim() : undefined;
214
+ const requestedPlanRelation: 'extend' | 'parallel' | undefined = args.plan_relation === 'extend' || args.plan_relation === 'parallel'
215
+ ? args.plan_relation
216
+ : undefined;
217
+ const relatedPlanId = typeof args.related_plan_id === 'string' && args.related_plan_id.trim() ? args.related_plan_id.trim() : undefined;
218
+ if (requestedRequirementId && !readRequirement({ controllerHome: context.controllerHome }, requestedRequirementId)) {
219
+ const facade = buildFacadeResult({
220
+ status: 'failed',
221
+ summary: `PLAN_REQUIREMENT_NOT_FOUND: ${requestedRequirementId}. Plan was not persisted; create or reconcile the Requirement authority first.`,
222
+ data: { executionStarted: false, planContractCreated: false, admissionDecision: 'missing_requirement', requirementId: requestedRequirementId },
223
+ });
224
+ return result(facade as unknown as Record<string, unknown>, true);
225
+ }
226
+
227
+ const admissionInput = {
228
+ requirementId: requestedRequirementId,
229
+ scopeKey: String(args.scope_key ?? ''),
230
+ planRelation: requestedPlanRelation,
231
+ relatedPlanId,
232
+ };
233
+ const renderPlanAdmission = (admission: ReturnType<typeof resolvePlanAdmission>): CallToolResult | undefined => {
234
+ if (admission.admissionDecision === 'create_new') return undefined;
235
+ if (admission.reason === 'exact_scope_authority' && admission.plan) {
236
+ const exactDraftRepair = admission.plan.status === 'draft' && requestedPlanId === admission.plan.planId;
237
+ const facade = buildFacadeResult({
238
+ summary: exactDraftRepair
239
+ ? `PLAN_DRAFT_REPAIR_REQUIRED: draft Plan ${admission.plan.planId} already owns scope ${admission.normalizedScopeKey}; preserve that authority and amend it through rh_work repair.`
240
+ : `PLAN_AUTHORITY_REUSED: active Plan ${admission.plan.planId} already owns scope ${admission.normalizedScopeKey}; no duplicate draft was created.`,
241
+ data: {
242
+ plan: summarizePlanContract(admission.plan),
243
+ executionStarted: false,
244
+ planContractCreated: false,
245
+ admissionDecision: 'reuse_existing',
246
+ resolutionRequired: false,
247
+ ...(exactDraftRepair ? { repairRequired: true } : {}),
248
+ },
249
+ suggestedNextActions: exactDraftRepair
250
+ ? [{
251
+ label: 'Repair this exact draft Plan',
252
+ tool: 'rh_work',
253
+ operation: 'repair',
254
+ payload: {
255
+ plan_id: admission.plan.planId,
256
+ repair_operation: 'repair',
257
+ dry_run: false,
258
+ scope_key: args.scope_key,
259
+ source_revision: args.source_revision,
260
+ objective: args.objective,
261
+ plan_steps: args.plan_steps,
262
+ non_goals: args.non_goals,
263
+ assumptions: args.assumptions,
264
+ resolved_decisions: args.resolved_decisions,
265
+ stop_conditions: args.stop_conditions,
266
+ replan_conditions: args.replan_conditions,
267
+ integration_strategy: args.integration_strategy,
268
+ },
269
+ risk: 'workspace_write',
270
+ confidence: 'high',
271
+ }]
272
+ : [{ label: 'Read active Plan', tool: 'rh_work', operation: 'plan_get', payload: { plan_id: admission.plan.planId }, risk: 'readonly', confidence: 'high' }],
273
+ });
274
+ return result(facade as unknown as Record<string, unknown>);
275
+ }
276
+ if (admission.reason === 'extension_target_required') {
277
+ const facade = buildFacadeResult({
278
+ summary: `PLAN_EXTENSION_TARGET_REQUIRED: select related_plan_id from the active Plan slices for Requirement ${requestedRequirementId}.`,
279
+ data: { executionStarted: false, planContractCreated: false, admissionDecision: 'resolution_required', resolutionRequired: true, candidates: admission.candidates.map(summarizePlanContract) },
280
+ });
281
+ return result(facade as unknown as Record<string, unknown>);
282
+ }
283
+ if (admission.reason === 'extend_existing' && admission.plan) {
284
+ // plan_create + plan_relation=extend revises the explicitly related stable
285
+ // Plan identity in place and advances its semantic head. Preflight continues
286
+ // into atomic admission; compatibility must not create a sibling revision Plan.
287
+ return undefined;
288
+ }
289
+ throw new Error(`PLAN_ADMISSION_RESULT_INVALID: ${admission.admissionDecision}:${admission.reason}`);
290
+ };
291
+
292
+ const plans = listPlanContracts({ ...store, status: 'all', limit: 100 });
293
+ const preflightAdmission = resolvePlanAdmission(plans, admissionInput);
294
+ const preflightResult = renderPlanAdmission(preflightAdmission);
295
+ if (preflightResult) return preflightResult;
296
+
297
+ const requestedPlanCheckIds = rawSteps
298
+ .filter((step): step is Record<string, unknown> => Boolean(step) && typeof step === 'object' && !Array.isArray(step))
299
+ .flatMap((step) => Array.isArray(step.check_ids) ? step.check_ids.map(String) : []);
300
+ const normalizedPlanChecks = normalizeCheckIds(requestedPlanCheckIds, context.checks);
301
+ if (normalizedPlanChecks.invalidCheckIds.length > 0) {
302
+ const facade = buildFacadeResult({
303
+ status: 'failed',
304
+ summary: `PLAN_CHECKS_INVALID: ${normalizedPlanChecks.invalidCheckIds.join(', ')}. Plan was not persisted; select replacement IDs from registeredCheckIds in this response, then request readiness only for the checks you choose.`,
305
+ data: {
306
+ executionStarted: false,
307
+ planContractCreated: false,
308
+ admissionDecision: 'invalid_checks',
309
+ normalizedChecks: normalizedPlanChecks,
310
+ registeredCheckIds: context.checks.map((check) => check.id).slice(0, 80),
311
+ },
312
+ suggestedNextActions: [],
313
+ });
314
+ return result(facade as unknown as Record<string, unknown>, true);
315
+ }
316
+
317
+ const admitted = await admitPlanContractAsync(store, {
318
+ planId: String(args.plan_id ?? ''),
319
+ repoId: context.repoId,
320
+ requirementId: requestedRequirementId,
321
+ scopeKey: String(args.scope_key ?? ''),
322
+ planRelation: requestedPlanRelation,
323
+ relatedPlanId,
324
+ sourceRevision: String(args.source_revision ?? ''),
325
+ goal: String(args.objective ?? ''),
326
+ nonGoals: Array.isArray(args.non_goals) ? args.non_goals.map(String) : undefined,
327
+ assumptions: Array.isArray(args.assumptions) ? args.assumptions.map(String) : undefined,
328
+ resolvedDecisions: Array.isArray(args.resolved_decisions) ? args.resolved_decisions.map(String) : undefined,
329
+ stopConditions: Array.isArray(args.stop_conditions) ? args.stop_conditions.map(String) : undefined,
330
+ replanConditions: Array.isArray(args.replan_conditions) ? args.replan_conditions.map(String) : undefined,
331
+ integrationStrategy: typeof args.integration_strategy === 'string' ? args.integration_strategy : undefined,
332
+ obligationDispositions: planObligationDispositionsFromArgs(args.obligation_dispositions),
333
+ steps: rawSteps.filter((step): step is Record<string, unknown> => Boolean(step) && typeof step === 'object' && !Array.isArray(step)).map((step) => ({
334
+ id: String(step.id ?? ''),
335
+ objective: String(step.objective ?? ''),
336
+ dependencies: Array.isArray(step.dependencies) ? step.dependencies.map(String) : [],
337
+ authoritativeFiles: Array.isArray(step.authoritative_files) ? step.authoritative_files.map(String) : [],
338
+ allowedPaths: Array.isArray(step.allowed_paths) ? step.allowed_paths.map(String) : [],
339
+ forbiddenPaths: Array.isArray(step.forbidden_paths) ? step.forbidden_paths.map(String) : [],
340
+ checks: Array.isArray(step.check_ids) ? step.check_ids.map(String) : [],
341
+ acceptanceCriteria: Array.isArray(step.acceptance_criteria) ? step.acceptance_criteria.map(String) : [],
342
+ })),
343
+ });
344
+ if (admitted.reason === 'extend_existing' && admitted.plan) {
345
+ const plan = admitted.plan;
346
+ const requestedLabel = requestedPlanId && requestedPlanId !== plan.planId
347
+ ? ` Requested compatibility plan_id ${requestedPlanId} was retained only as revision audit metadata.`
348
+ : '';
349
+ const facade = buildFacadeResult({
350
+ summary: `PLAN_REVISION_REUSED_AUTHORITY: Plan ${plan.planId} was revised in place; no successor PlanContract was created.${requestedLabel}`,
351
+ data: {
352
+ plan: summarizePlanContract(plan),
353
+ executionStarted: false,
354
+ planContractCreated: false,
355
+ admissionDecision: 'reuse_existing',
356
+ resolutionRequired: false,
357
+ },
358
+ // Plan approval is a retired ceremony no-op; the projection must not steer
359
+ // the model back into it. Reading the current revision is the honest action.
360
+ suggestedNextActions: [{ label: 'Read current Plan revision', tool: 'rh_work', operation: 'plan_get', payload: { plan_id: plan.planId }, risk: 'readonly', confidence: 'high' }],
361
+ });
362
+ return result(facade as unknown as Record<string, unknown>);
363
+ }
364
+ const racedAdmissionResult = renderPlanAdmission(admitted);
365
+ if (racedAdmissionResult) return racedAdmissionResult;
366
+ if (!admitted.plan) throw new Error('PLAN_ADMISSION_CREATE_MISSING_PLAN');
367
+ const plan = admitted.plan;
368
+ const facade = buildFacadeResult({
369
+ summary: `PlanContract ${plan.planId} created as draft after atomic authority admission; no execution was started.`,
370
+ data: { plan: summarizePlanContract(plan), executionStarted: false, planContractCreated: true, admissionDecision: 'create_new' },
371
+ suggestedNextActions: [{ label: 'Read current Plan revision', tool: 'rh_work', operation: 'plan_get', payload: { plan_id: plan.planId }, risk: 'readonly', confidence: 'high' }],
372
+ });
373
+ return result(facade as unknown as Record<string, unknown>);
374
+ } catch (error) {
375
+ const facade = buildFacadeResult({
376
+ status: 'blocked',
377
+ summary: error instanceof Error ? error.message : 'PlanContract operation failed.',
378
+ data: { operation, executionStarted: false },
379
+ });
380
+ return result(facade as unknown as Record<string, unknown>, true);
381
+ }
382
+ }