@moretea-labs/forge 1.8.0 → 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 (695) hide show
  1. package/AGENTS.md +73 -7
  2. package/CHANGELOG.md +34 -0
  3. package/CLAUDE.md +17 -2
  4. package/CONTRIBUTING.md +3 -2
  5. package/README.en.md +24 -3
  6. package/README.md +10 -6
  7. package/README.zh-CN.md +5 -3
  8. package/THIRD_PARTY_NOTICES.md +1 -2
  9. package/adapters/chatgpt/browser-delivery-host.ts +7 -1
  10. package/adapters/chatgpt/browser-delivery-runtime.ts +531 -56
  11. package/adapters/chatgpt/controller-binding-store.ts +101 -22
  12. package/adapters/chatgpt/controller-round-host.ts +15 -25
  13. package/adapters/chatgpt/controller-round-settlement-store.ts +58 -4
  14. package/adapters/chatgpt/provider-delivery.ts +229 -2
  15. package/adapters/chatgpt/work-conversation-binding-store.ts +99 -54
  16. package/adapters/computer/chatgpt-extension-target.ts +708 -0
  17. package/adapters/computer/chrome-extension/background.js +541 -0
  18. package/adapters/computer/chrome-extension/content.js +402 -0
  19. package/adapters/computer/chrome-extension/core.js +24 -0
  20. package/adapters/computer/chrome-extension/manifest.json +32 -0
  21. package/adapters/computer/desktop-operator-discovery.ts +11 -31
  22. package/adapters/computer/desktop-operator-provider.ts +18 -6
  23. package/adapters/computer/interaction-target-authority.ts +178 -24
  24. package/adapters/mcp/access-mode.ts +18 -39
  25. package/adapters/mcp/auth.ts +2 -7
  26. package/adapters/mcp/instructions.ts +6 -5
  27. package/adapters/mcp/multi-repository.ts +10 -47
  28. package/adapters/mcp/oauth.ts +73 -0
  29. package/adapters/mcp/paths.ts +4 -1
  30. package/adapters/mcp/runtime-gateway/bounded-result-runtime.ts +62 -0
  31. package/adapters/mcp/runtime-gateway/cognition-settlement.ts +201 -0
  32. package/adapters/mcp/runtime-gateway/context-adapter.ts +490 -113
  33. package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +83 -0
  34. package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +20 -5
  35. package/adapters/mcp/runtime-gateway/core-capability-adapter.ts +258 -0
  36. package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +10 -27
  37. package/adapters/mcp/runtime-gateway/engineering-tool-contract.ts +15 -0
  38. package/adapters/mcp/runtime-gateway/execution-tools.ts +14 -54
  39. package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +2 -1
  40. package/adapters/mcp/runtime-gateway/plugin-adapter.ts +132 -47
  41. package/adapters/mcp/runtime-gateway/process-tools.ts +173 -23
  42. package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +16 -4
  43. package/adapters/mcp/runtime-gateway/recovery-adapter.ts +69 -52
  44. package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +4 -35
  45. package/adapters/mcp/runtime-gateway/result-adapter.ts +10 -4
  46. package/adapters/mcp/runtime-gateway/router.ts +19 -507
  47. package/adapters/mcp/runtime-gateway/routing-policy.ts +506 -0
  48. package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +15 -66
  49. package/adapters/mcp/runtime-gateway/runtime-readiness-observation.ts +218 -0
  50. package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +123 -178
  51. package/adapters/mcp/runtime-gateway/runtime-tools.ts +11 -5
  52. package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +37 -1
  53. package/adapters/mcp/runtime-gateway/shared-adapter.ts +20 -0
  54. package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +416 -270
  55. package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +140 -0
  56. package/adapters/mcp/runtime-gateway/work-adapter.ts +262 -3123
  57. package/adapters/mcp/runtime-gateway/work-controller-operations.ts +257 -0
  58. package/adapters/mcp/runtime-gateway/work-detail-projection.ts +60 -0
  59. package/adapters/mcp/runtime-gateway/work-input-wire-migration.ts +229 -0
  60. package/adapters/mcp/runtime-gateway/work-learning-operations.ts +145 -0
  61. package/adapters/mcp/runtime-gateway/work-list-projection.ts +38 -0
  62. package/adapters/mcp/runtime-gateway/work-plan-operations.ts +382 -0
  63. package/adapters/mcp/runtime-gateway/work-repair-adapter.ts +308 -0
  64. package/adapters/mcp/runtime-gateway/work-requirement-operations.ts +148 -0
  65. package/adapters/mcp/runtime-gateway/work-semantic-operations.ts +320 -0
  66. package/adapters/mcp/runtime-gateway/work-workflow-operations.ts +113 -0
  67. package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +180 -0
  68. package/adapters/mcp/server.ts +91 -26
  69. package/adapters/mcp/setup.ts +5 -13
  70. package/adapters/mcp/tool-mapping/access-tools.ts +0 -6
  71. package/adapters/mcp/tool-mapping/legacy-tool-service.ts +703 -3092
  72. package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +5 -10
  73. package/adapters/mcp/tool-mapping/repository-tools.ts +170 -213
  74. package/adapters/mcp/toolset-names.ts +11 -37
  75. package/adapters/mcp/toolset.ts +19 -92
  76. package/{src/cli → adapters}/mcp/transports/AGENTS.md +5 -5
  77. package/{src/cli → adapters}/mcp/transports/CLAUDE.md +5 -5
  78. package/adapters/mcp/transports/http-observation.ts +377 -0
  79. package/adapters/mcp/transports/http-post-lifecycle.ts +19 -0
  80. package/adapters/mcp/transports/http.ts +200 -683
  81. package/adapters/mcp/transports/oauth-http.ts +322 -0
  82. package/adapters/mcp/transports/session-registry.ts +6 -0
  83. package/adapters/mcp/tunnels/openai-secure-tunnel.ts +89 -5
  84. package/adapters/mcp/types.ts +0 -6
  85. package/assets/hooks/lib/session-state.sh +0 -38
  86. package/assets/hooks/post-bash.sh +1 -1
  87. package/assets/hooks/post-tool-observer.sh +0 -5
  88. package/assets/hooks/prompt-guard.sh +0 -55
  89. package/assets/partials/04-project-structure.partial.md +1 -1
  90. package/assets/partials/07-footer.partial.md +1 -1
  91. package/assets/partials-agents/02-operating-mode.partial.md +1 -1
  92. package/assets/partials-agents/08-deep-docs.partial.md +1 -1
  93. package/assets/plugin-registry.v1.json +6 -4
  94. package/assets/reference-configs/agentic-development-flow.md +26 -1
  95. package/assets/reference-configs/external-tooling.md +0 -76
  96. package/assets/reference-configs/global-working-rules.md +19 -0
  97. package/assets/reference-configs/release-deploy.md +1 -1
  98. package/assets/templates/helpers/architecture-queue.sh +1 -1
  99. package/assets/templates/helpers/check-agent-tooling.sh +1 -327
  100. package/assets/templates/helpers/check-task-workflow.sh +1 -1
  101. package/assets/templates/helpers/ensure-task-workflow.sh +0 -14
  102. package/assets/templates/helpers/migrate-project-template.sh +2 -2
  103. package/assets/workflow-contract.v1.json +0 -2
  104. package/docs/README.md +5 -2
  105. package/docs/architecture/CURRENT.md +205 -51
  106. package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +14 -5
  107. package/docs/architecture/decisions/20260823-immediate-controller-relay.md +6 -3
  108. package/docs/architecture/decisions/20260904-ios-device-migration-baseline.md +42 -0
  109. package/docs/architecture/decisions/20260907-assistant-learning-loop.md +2 -0
  110. package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +19 -4
  111. package/docs/architecture/decisions/20260916-workflow-supervisor-authority.md +249 -0
  112. package/docs/architecture/decisions/20260917-cognitive-memory-foundation.md +82 -0
  113. package/docs/architecture/decisions/20260918-stable-candidate-release-lifecycle.md +234 -0
  114. package/docs/architecture/decisions/20260919-autonomous-work-liveness.md +62 -0
  115. package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +74 -0
  116. package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +342 -0
  117. package/docs/architecture/decisions/20261005-forge-v3-desktop-client-boundary.md +77 -0
  118. package/docs/architecture/decisions/20261009-exact-code-context-discovery.md +19 -0
  119. package/docs/architecture/decisions/20261009-generated-xcode-cache-retention.md +37 -0
  120. package/docs/architecture/decisions/20261011-autonomous-continuation-convergence.md +597 -0
  121. package/docs/architecture/decisions/20261017-edit-session-finalization-reconciliation.md +17 -0
  122. package/docs/architecture/decisions/20261019-retire-host-skills.md +16 -0
  123. package/docs/architecture/diagrams/agentic-dev-plugin-architecture.html +1 -1
  124. package/docs/architecture/domains/public-surface.md +3 -5
  125. package/docs/architecture/domains/verification.md +6 -5
  126. package/docs/architecture/domains/workflow-engine.md +6 -0
  127. package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +3 -3
  128. package/docs/architecture/requests/2026-09-04-computer-plugin-workflow-taxonomy.md +4 -4
  129. package/docs/architecture/reviews/20261015-code-search-runtime-acceptance.md +75 -0
  130. package/docs/forge-plugin-management.md +16 -4
  131. package/docs/operations/controller-browser-plugin.md +23 -0
  132. package/docs/operations/controller-performance-and-502.md +17 -0
  133. package/docs/operations/controller-reliability-runbook.md +2 -2
  134. package/docs/operations/features.md +6 -7
  135. package/docs/operations/features.zh-CN.md +1 -1
  136. package/docs/operations/github-repository.md +4 -4
  137. package/docs/operations/github-semantic-release-projection.md +20 -0
  138. package/docs/operations/homebrew.md +2 -2
  139. package/docs/operations/mcp-tool-exposure.md +13 -52
  140. package/docs/operations/releasing.md +2 -0
  141. package/docs/operations/runtime-performance-diagnostics.md +8 -0
  142. package/docs/operations/standalone-disaster-recovery.md +15 -7
  143. package/docs/tutorials/01-install-and-start.zh-CN.md +1 -1
  144. package/docs/tutorials/03-first-repository-task.md +2 -0
  145. package/docs/wiki/Computer-and-Plugins.md +78 -0
  146. package/docs/wiki/Computer-and-Plugins.zh-CN.md +88 -0
  147. package/docs/wiki/Home.md +16 -2
  148. package/docs/wiki/Implementation.md +25 -13
  149. package/docs/wiki/Installation.md +28 -32
  150. package/docs/wiki/Integrations.md +4 -0
  151. package/docs/wiki/Quick-Start.md +35 -22
  152. package/docs/wiki/Releases-and-Upgrades.md +15 -25
  153. package/docs/wiki/_Sidebar.md +5 -1
  154. package/package.json +25 -25
  155. package/packages/kernel/cognition/api/index.ts +6 -0
  156. package/packages/kernel/cognition/application/activation-service.ts +451 -0
  157. package/packages/kernel/cognition/application/consolidation-service.ts +185 -0
  158. package/packages/kernel/cognition/application/legacy-experience-adapter.ts +38 -0
  159. package/packages/kernel/cognition/application/memory-service.ts +64 -0
  160. package/packages/kernel/cognition/domain/learning.ts +106 -0
  161. package/packages/kernel/cognition/domain/memory.ts +254 -0
  162. package/packages/kernel/controller/api/index.ts +1 -0
  163. package/packages/kernel/controller/application/continuation-service.ts +281 -0
  164. package/packages/kernel/controller/application/controller-round-service.ts +12 -0
  165. package/packages/kernel/controller/domain/controller-round-transition-policy.ts +242 -21
  166. package/packages/kernel/controller/domain/controller-round.ts +4 -1
  167. package/packages/kernel/controller/domain/execution-quality.ts +3 -1
  168. package/packages/kernel/controller/infrastructure/controller-round-store.ts +689 -103
  169. package/packages/kernel/controller/infrastructure/controller-session-store.ts +348 -97
  170. package/packages/kernel/controller/ports/controller-host.ts +2 -0
  171. package/packages/kernel/identity/api/index.ts +10 -0
  172. package/packages/kernel/identity/domain/activity-projection.ts +43 -0
  173. package/packages/kernel/identity/domain/capability-broker.ts +60 -0
  174. package/packages/kernel/identity/domain/grant.ts +72 -0
  175. package/packages/kernel/identity/domain/owned-resource.ts +116 -0
  176. package/packages/kernel/identity/domain/user-request.ts +93 -0
  177. package/packages/kernel/identity/infrastructure/activity-projection-store.ts +87 -0
  178. package/packages/kernel/identity/infrastructure/capability-broker.ts +81 -0
  179. package/packages/kernel/identity/infrastructure/grant-store.ts +284 -0
  180. package/packages/kernel/identity/infrastructure/owned-resource-store.ts +259 -0
  181. package/packages/kernel/identity/infrastructure/user-request-store.ts +182 -0
  182. package/packages/kernel/scheduler/api/index.ts +0 -2
  183. package/packages/kernel/scheduler/application/eligibility.ts +4 -1
  184. package/packages/kernel/scheduler/application/schedule-service.ts +3 -0
  185. package/packages/kernel/scheduler/application/settlement.ts +0 -15
  186. package/packages/kernel/scheduler/domain/schedule.ts +87 -0
  187. package/packages/kernel/scheduler/infrastructure/schedule-store.ts +166 -143
  188. package/packages/kernel/work/api/index.ts +3 -2
  189. package/packages/kernel/work/application/work-service.ts +18 -42
  190. package/packages/kernel/work/domain/current-task-lineage.ts +104 -0
  191. package/packages/kernel/work/domain/engineering-design.ts +10 -5
  192. package/packages/kernel/work/domain/engineering-profile.ts +8 -12
  193. package/packages/kernel/work/domain/evaluation-promotion-receipt.ts +186 -0
  194. package/packages/kernel/work/domain/execution-concurrency.ts +19 -26
  195. package/packages/kernel/work/domain/execution-snapshot.ts +0 -31
  196. package/packages/kernel/work/domain/implementation-review.ts +14 -331
  197. package/packages/kernel/work/domain/objective-graph.ts +119 -0
  198. package/packages/kernel/work/domain/project-engineering-contract.ts +23 -1
  199. package/packages/kernel/work/domain/repository-completion-receipt.ts +1 -1
  200. package/packages/kernel/work/domain/state-machine.ts +34 -65
  201. package/packages/kernel/work/domain/types.ts +57 -51
  202. package/packages/kernel/work/infrastructure/work-contract-store.ts +847 -729
  203. package/packages/kernel/work/ports/work-contract-store.ts +5 -2
  204. package/packages/plugin-runtime/browser/provider-registry.ts +12 -36
  205. package/packages/plugin-runtime/browser/session-authority.ts +2 -1
  206. package/packages/plugin-runtime/computer/chatgpt-identity.ts +24 -0
  207. package/packages/plugin-runtime/computer/conversation-target.ts +153 -0
  208. package/packages/plugin-runtime/computer/index.ts +2 -0
  209. package/packages/plugin-runtime/computer/target-authority.ts +26 -1
  210. package/packages/plugin-runtime/external/unix-jsonl-transport.ts +142 -18
  211. package/packages/protocols/computer/contract.ts +27 -1
  212. package/scripts/activate-source-baseline.ts +7 -9
  213. package/scripts/assemble-template.ts +11 -72
  214. package/scripts/canary-controller-semantic-wait.ts +12 -24
  215. package/scripts/check-mcp-compatibility.ts +94 -201
  216. package/scripts/check-package-identity.mjs +0 -5
  217. package/scripts/check-runtime-architecture.mjs +921 -239
  218. package/scripts/forge-local-recovery-helper.mjs +93 -15
  219. package/scripts/init-project.sh +0 -46
  220. package/scripts/install-ios-hid-toolchain.sh +60 -0
  221. package/scripts/install-standalone-recovery.ts +1 -1
  222. package/scripts/lib/project-init-lib.sh +6 -3
  223. package/scripts/migrate-windows-wsl-controller-home.ts +2 -0
  224. package/scripts/open-source-audit-allowlist.txt +1 -3
  225. package/scripts/run-bounded-command.mjs +5 -0
  226. package/scripts/run-governed-gate.ts +2 -1
  227. package/scripts/run-mobile-monitor-bridge.ts +0 -1
  228. package/scripts/smoke-control-plane-failure-domain.ts +94 -0
  229. package/scripts/smoke-ios-physical-device.ts +38 -10
  230. package/scripts/smoke-mcp-http-runtime.ts +12 -8
  231. package/scripts/smoke-mcp-tool-surface.ts +27 -41
  232. package/scripts/smoke-runtime-recovery.ts +12 -43
  233. package/scripts/smoke-schedule-engine.ts +23 -15
  234. package/scripts/smoke-unattended-transport-recovery.ts +223 -0
  235. package/scripts/smoke-user-request-continuation-restart.ts +232 -0
  236. package/scripts/smoke-workflow-supervisor-chrome-adapter.ts +95 -0
  237. package/scripts/smoke-workflow-supervisor-process-restart.ts +276 -0
  238. package/scripts/smoke-workflow-supervisor-restart-recovery.ts +150 -0
  239. package/scripts/smoke-workflow-supervisor.ts +103 -0
  240. package/scripts/sync-generated-authority.mjs +0 -1
  241. package/scripts/verify-forge-runtime.sh +2 -1
  242. package/src/cli/agent-jobs/executor-health.ts +12 -35
  243. package/src/cli/agent-jobs/integration.ts +20 -51
  244. package/src/cli/agent-jobs/job-manager.ts +7 -3
  245. package/src/cli/chatgpt-browser/file-policy.ts +2 -2
  246. package/src/cli/commands/brain-assistant.ts +27 -13
  247. package/src/cli/commands/brain.ts +13 -15
  248. package/src/cli/commands/chatgpt.ts +1 -163
  249. package/src/cli/commands/doctor.ts +1 -143
  250. package/src/cli/commands/global-runtime.ts +3 -196
  251. package/src/cli/commands/init-hook.ts +6 -23
  252. package/src/cli/commands/init.ts +3 -252
  253. package/src/cli/commands/mcp.ts +0 -5
  254. package/src/cli/commands/prompt-guard-decision.ts +0 -2
  255. package/src/cli/commands/recovery.ts +137 -135
  256. package/src/cli/commands/repository.ts +17 -1
  257. package/src/cli/commands/runtime.ts +3 -3
  258. package/src/cli/commands/setup-execution.ts +41 -0
  259. package/src/cli/commands/setup-profile.ts +8 -0
  260. package/src/cli/controller/check-runner.ts +13 -2
  261. package/src/cli/controller/completion-backlog.ts +3 -3
  262. package/src/cli/controller/completion-orchestrator.ts +5 -44
  263. package/src/cli/controller/completion-target.ts +3 -72
  264. package/src/cli/controller/composite-operations.ts +1 -1
  265. package/src/cli/controller/context/instruction-context.ts +1 -1
  266. package/src/cli/controller/context/known-paths.ts +2 -2
  267. package/src/cli/controller/context/query-planning.ts +11 -4
  268. package/src/cli/controller/context/rule-resolution.ts +2 -2
  269. package/src/cli/controller/context/source-materializer.ts +83 -102
  270. package/src/cli/controller/context/structural-provider.ts +84 -0
  271. package/src/cli/controller/context/structural.ts +6 -6
  272. package/src/cli/controller/context/types.ts +8 -9
  273. package/src/cli/controller/context-pack.ts +107 -84
  274. package/src/cli/controller/execution-completion.ts +4 -7
  275. package/src/cli/controller/execution-policy.ts +36 -153
  276. package/src/cli/controller/governance.ts +2 -3
  277. package/src/cli/controller/issue-store.ts +4 -99
  278. package/src/cli/controller/launch-agents.ts +59 -18
  279. package/src/cli/controller/operational-plan.ts +25 -52
  280. package/src/cli/controller/runtime-config.ts +5 -1
  281. package/src/cli/controller/stuck-state-migration.ts +2 -3
  282. package/src/cli/controller/systemd-user.ts +42 -10
  283. package/src/cli/editing/edit-session.ts +18 -12
  284. package/src/cli/github/github.ts +4 -4
  285. package/src/cli/github/semantic-projection.ts +174 -0
  286. package/src/cli/hook/prompt-intents.ts +0 -9
  287. package/src/cli/index.ts +1 -43
  288. package/src/cli/local-bridge/connector-freshness.ts +1 -12
  289. package/src/cli/local-bridge/console-automations.ts +19 -14
  290. package/src/cli/local-bridge/console-view-models.ts +4 -13
  291. package/src/cli/local-bridge/facade-api.ts +64 -193
  292. package/src/cli/local-bridge/server.ts +24 -147
  293. package/src/cli/local-bridge/types.ts +0 -1
  294. package/src/cli/mcp/oauth-client-retirement.ts +74 -0
  295. package/src/cli/repositories/command-classifier.ts +0 -9
  296. package/src/cli/repositories/command-executor.ts +29 -23
  297. package/src/cli/repositories/command-scope.ts +37 -18
  298. package/src/cli/repositories/controller-home.ts +48 -0
  299. package/src/cli/repositories/ephemeral-workspace.ts +20 -30
  300. package/src/cli/repositories/git-command-executor.ts +2 -2
  301. package/src/cli/repositories/locks.ts +20 -0
  302. package/src/cli/repositories/registry.ts +79 -12
  303. package/src/cli/repositories/safe-patch.ts +2 -12
  304. package/src/cli/repositories/structured-git.ts +101 -5
  305. package/src/cli/repository/inspector.ts +185 -343
  306. package/src/cli/repository/session-cache.ts +92 -6
  307. package/src/effects/process-runner.ts +17 -1
  308. package/src/runtime/context/assistant-context.ts +20 -7
  309. package/src/runtime/context/assistant-work-context.ts +89 -27
  310. package/src/runtime/context/automatic-learning.ts +565 -0
  311. package/src/runtime/context/cognitive-attention.ts +173 -0
  312. package/src/runtime/context/cognitive-skill-canary.ts +158 -0
  313. package/src/runtime/context/context-closure.ts +46 -9
  314. package/src/runtime/context/context-pack-process.ts +103 -0
  315. package/src/runtime/context/context-plane.ts +1 -9
  316. package/src/runtime/context/direct-controller-learning.ts +298 -0
  317. package/src/runtime/context/generic-lsp-provider.ts +1 -1
  318. package/src/runtime/context/semantic-navigation-contract.ts +16 -0
  319. package/src/runtime/context/semantic-navigation.ts +7 -35
  320. package/src/runtime/context/typescript-navigation-process.ts +145 -0
  321. package/src/runtime/context/typescript-navigation.ts +89 -3
  322. package/src/runtime/control-plane/cleanup-artifact-retention.ts +215 -12
  323. package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +9 -47
  324. package/src/runtime/control-plane/execution/controller-authority-recovery.ts +34 -4
  325. package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +29 -20
  326. package/src/runtime/control-plane/execution/execution-identity.ts +23 -3
  327. package/src/runtime/control-plane/execution/repository-work-attribution.ts +7 -30
  328. package/src/runtime/control-plane/execution/retained-work-resume.ts +206 -199
  329. package/src/runtime/control-plane/execution/session-store.ts +31 -1
  330. package/src/runtime/control-plane/execution/validation.ts +6 -8
  331. package/src/runtime/control-plane/execution/work-authority-reconciler.ts +13 -42
  332. package/src/runtime/control-plane/execution/work-check-evidence.ts +137 -0
  333. package/src/runtime/control-plane/execution/work-completion-authority.ts +30 -85
  334. package/src/runtime/control-plane/execution/work-delivery-service.ts +616 -0
  335. package/src/runtime/control-plane/execution/work-evidence-policy.ts +12 -50
  336. package/src/runtime/control-plane/execution/work-execution-support.ts +50 -149
  337. package/src/runtime/control-plane/execution/work-handle-authority.ts +197 -110
  338. package/src/runtime/control-plane/execution/work-handle-store.ts +72 -44
  339. package/src/runtime/control-plane/execution/work-head-settlement.ts +53 -20
  340. package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +52 -29
  341. package/src/runtime/control-plane/execution/work-operation-service.ts +60 -34
  342. package/src/runtime/control-plane/execution/work-preparation-service.ts +231 -267
  343. package/src/runtime/control-plane/execution/work-process-evidence.ts +2 -2
  344. package/src/runtime/control-plane/execution/work-remote-delivery.ts +2 -3
  345. package/src/runtime/control-plane/execution/work-revision-diff.ts +39 -0
  346. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +201 -199
  347. package/src/runtime/control-plane/execution/work-validation-reconciler.ts +33 -85
  348. package/src/runtime/control-plane/execution/work-verification-service.ts +406 -50
  349. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +6 -2
  350. package/src/runtime/control-plane/facade/capability-registry.ts +364 -37
  351. package/src/runtime/control-plane/facade/check-normalization.ts +3 -9
  352. package/src/runtime/control-plane/facade/codex-delegation.ts +10 -11
  353. package/src/runtime/control-plane/facade/controller-connection.ts +135 -0
  354. package/src/runtime/control-plane/facade/goal-workloop-access.ts +1 -20
  355. package/src/runtime/control-plane/facade/goal-workloop.ts +281 -1753
  356. package/src/runtime/control-plane/facade/handoff-inbox-application.ts +12 -25
  357. package/src/runtime/control-plane/facade/handoff-inbox-store.ts +256 -52
  358. package/src/runtime/control-plane/facade/index.ts +0 -1
  359. package/src/runtime/control-plane/facade/operation-digest.ts +12 -15
  360. package/src/runtime/control-plane/facade/plan-contract-store.ts +451 -991
  361. package/src/runtime/control-plane/facade/policy-gate.ts +0 -23
  362. package/src/runtime/control-plane/facade/repository-work-admission.ts +12 -22
  363. package/src/runtime/control-plane/facade/requirement-authority.ts +102 -199
  364. package/src/runtime/control-plane/facade/requirement-board.ts +3 -3
  365. package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +51 -14
  366. package/src/runtime/control-plane/facade/self-healing-loop.ts +18 -53
  367. package/src/runtime/control-plane/facade/suggested-actions.ts +15 -18
  368. package/src/runtime/control-plane/facade/types.ts +49 -108
  369. package/src/runtime/control-plane/facade/work-continuation.ts +9 -9
  370. package/src/runtime/control-plane/generated-cache-retention.ts +206 -59
  371. package/src/runtime/control-plane/global-scheduler/autonomous-continuation.ts +248 -0
  372. package/src/runtime/control-plane/global-scheduler/durable-admission.ts +1 -1
  373. package/src/runtime/control-plane/global-scheduler/maintenance.ts +256 -117
  374. package/src/runtime/control-plane/global-scheduler/reconciliation.ts +3 -12
  375. package/src/runtime/control-plane/global-scheduler/scheduler.ts +66 -40
  376. package/src/runtime/control-plane/global-scheduler/wake-signal.ts +42 -2
  377. package/src/runtime/control-plane/governance/access-policy.ts +19 -2
  378. package/src/runtime/control-plane/governance/authorization.ts +20 -3
  379. package/src/runtime/control-plane/governance/external-effects.ts +1 -1
  380. package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +63 -300
  381. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +29 -300
  382. package/src/runtime/control-plane/launcher/local-conversation-controller.ts +238 -0
  383. package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +5 -2
  384. package/src/runtime/control-plane/launcher/thin-launcher.ts +96 -240
  385. package/src/runtime/control-plane/persistence/cognition-store.ts +820 -0
  386. package/src/runtime/control-plane/persistence/experience-store.ts +162 -29
  387. package/src/runtime/control-plane/persistence/requirement-store.ts +216 -74
  388. package/src/runtime/control-plane/persistence/sqlite-store.ts +113 -6
  389. package/src/runtime/control-plane/release-retention.ts +135 -47
  390. package/src/runtime/control-plane/repository-namespace-retention.ts +2 -2
  391. package/src/runtime/control-plane/runtime-cleanup.ts +295 -107
  392. package/src/runtime/control-plane/workspace/project-onboarding.ts +80 -0
  393. package/src/runtime/control-plane/workspace/semantic-sync-service.ts +19 -5
  394. package/src/runtime/control-plane/workspace/workspace-store.ts +169 -0
  395. package/src/runtime/diagnostics/incident-repair.ts +313 -146
  396. package/src/runtime/diagnostics/mcp-timing.ts +114 -0
  397. package/src/runtime/evidence/artifact-store.ts +158 -40
  398. package/src/runtime/evidence/evidence-store.ts +112 -8
  399. package/src/runtime/evidence/output-handle-index.ts +225 -0
  400. package/src/runtime/evidence/result-store.ts +158 -44
  401. package/src/runtime/evidence/sensitive-output.ts +22 -2
  402. package/src/runtime/execution/jobs/child-reference.ts +11 -0
  403. package/src/runtime/execution/jobs/receipt-recovery.ts +1 -11
  404. package/src/runtime/execution/jobs/store.ts +3 -4
  405. package/src/runtime/execution/managed-workspace.ts +57 -0
  406. package/src/runtime/execution/process-runtime/check-facade.ts +1 -1
  407. package/src/runtime/execution/process-runtime/check-result-retention.ts +2 -2
  408. package/src/runtime/execution/process-runtime/check-result.ts +105 -1
  409. package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +18 -8
  410. package/src/runtime/execution/process-runtime/command-facade.ts +82 -30
  411. package/src/runtime/execution/process-runtime/gc.ts +15 -2
  412. package/src/runtime/execution/process-runtime/handle-index.ts +176 -0
  413. package/src/runtime/execution/process-runtime/host-command-lane.ts +139 -0
  414. package/src/runtime/execution/process-runtime/index.ts +3 -0
  415. package/src/runtime/execution/process-runtime/lightweight-managed.ts +251 -72
  416. package/src/runtime/execution/process-runtime/persisted-check.ts +3 -3
  417. package/src/runtime/execution/process-runtime/process-runner-entry.ts +47 -5
  418. package/src/runtime/execution/process-runtime/process-scope.ts +160 -0
  419. package/src/runtime/execution/process-runtime/resource-claims.ts +65 -61
  420. package/src/runtime/execution/process-runtime/runtime.ts +55 -18
  421. package/src/runtime/execution/process-runtime/store.ts +30 -2
  422. package/src/runtime/execution/process-runtime/types.ts +6 -1
  423. package/src/runtime/execution/thin-harness/execution-router.ts +16 -16
  424. package/src/runtime/execution/thin-harness/fast-executor.ts +2 -2
  425. package/src/runtime/execution/thin-harness/search-worker.ts +2 -2
  426. package/src/runtime/execution/workers/executor.ts +3 -8
  427. package/src/runtime/maintenance/cleanup.ts +41 -5
  428. package/src/runtime/platform/service-inventory.ts +130 -0
  429. package/src/runtime/platform/service-manager.ts +8 -0
  430. package/src/runtime/plugins/action-application.ts +97 -29
  431. package/src/runtime/plugins/app-store-connect-adapter.ts +290 -18
  432. package/src/runtime/plugins/browser-adapter.ts +1124 -333
  433. package/src/runtime/plugins/browser-automation-service.ts +23 -3
  434. package/src/runtime/plugins/browser-macos-bridge.ts +431 -137
  435. package/src/runtime/plugins/browser-manifest-surface.ts +47 -12
  436. package/src/runtime/plugins/browser-native-session-service.ts +63 -13
  437. package/src/runtime/plugins/browser-registration.ts +18 -0
  438. package/src/runtime/plugins/browser-runtime.ts +40 -36
  439. package/src/runtime/plugins/browser-session-authority.ts +2 -2
  440. package/src/runtime/plugins/browser-session-store.ts +46 -76
  441. package/src/runtime/plugins/capability-authorization-grants.ts +258 -62
  442. package/src/runtime/plugins/computer-chatgpt-browser-adapter-installer.ts +228 -0
  443. package/src/runtime/plugins/computer-registration.ts +298 -20
  444. package/src/runtime/plugins/desktop-operator-external-policy.ts +36 -4
  445. package/src/runtime/plugins/desktop-operator-registration.ts +12 -4
  446. package/src/runtime/plugins/external-adapter.ts +42 -6
  447. package/src/runtime/plugins/external-registration.ts +21 -1
  448. package/src/runtime/plugins/github-adapter.ts +30 -3
  449. package/src/runtime/plugins/gmail-adapter.ts +189 -3
  450. package/src/runtime/plugins/google-calendar-adapter.ts +2 -2
  451. package/src/runtime/plugins/google-shared.ts +24 -12
  452. package/src/runtime/plugins/google-tasks-adapter.ts +2 -2
  453. package/src/runtime/plugins/ios/remote-xpc-hid.ts +70 -30
  454. package/src/runtime/plugins/ios-adapter.ts +46 -41
  455. package/src/runtime/plugins/ios-agent-device.ts +54 -4
  456. package/src/runtime/plugins/ios-device-ownership.ts +103 -0
  457. package/src/runtime/plugins/ios-physical-device.ts +497 -79
  458. package/src/runtime/plugins/lightweight-action.ts +208 -2
  459. package/src/runtime/plugins/local-system-adapter.ts +12 -100
  460. package/src/runtime/plugins/managed-process-adapter.ts +12 -5
  461. package/src/runtime/plugins/plugin-action-sidecar.ts +17 -13
  462. package/src/runtime/plugins/plugin-management-adapter.ts +1 -1
  463. package/src/runtime/plugins/store.ts +682 -435
  464. package/src/runtime/plugins/types.ts +24 -0
  465. package/src/runtime/plugins/xiaohongshu-publish.ts +16 -0
  466. package/src/runtime/projections/git-status-sampler.ts +2 -19
  467. package/src/runtime/projections/invalidation.ts +7 -3
  468. package/src/runtime/projections/materialized-view.ts +80 -36
  469. package/src/runtime/recovery/actions.ts +4 -4
  470. package/src/runtime/recovery/capability-action-application.ts +46 -45
  471. package/src/runtime/recovery/lifecycle-inventory.ts +30 -40
  472. package/src/runtime/recovery/maintenance-executor.ts +374 -123
  473. package/src/runtime/recovery/probe.ts +2 -2
  474. package/src/runtime/recovery/store.ts +29 -11
  475. package/src/runtime/release/release-coordinator.ts +312 -0
  476. package/src/runtime/release/release-session.ts +716 -0
  477. package/src/runtime/release/release-state-migration.ts +25 -0
  478. package/src/runtime/resources/leases/store.ts +56 -25
  479. package/src/runtime/root/computer-composition.ts +191 -6
  480. package/src/runtime/root/controller-progression-composition.ts +254 -0
  481. package/src/runtime/root/controller-round-composition.ts +20 -1
  482. package/src/runtime/root/deployment-topology.ts +106 -0
  483. package/src/runtime/root/entry.ts +4 -3
  484. package/src/runtime/root/known-good-recovery.ts +184 -0
  485. package/src/runtime/root/local-bridge.ts +0 -1
  486. package/src/runtime/root/mcp-transport.ts +111 -18
  487. package/src/runtime/root/ownership.ts +261 -9
  488. package/src/runtime/root/package-connector-service.ts +227 -29
  489. package/src/runtime/root/package-runtime-release.ts +117 -30
  490. package/src/runtime/root/package-runtime-service.ts +24 -24
  491. package/src/runtime/root/release-execution-canary.ts +57 -12
  492. package/src/runtime/root/release-loader.ts +90 -8
  493. package/src/runtime/root/release-manifest.ts +80 -40
  494. package/src/runtime/root/release-materialize.ts +372 -106
  495. package/src/runtime/root/release-store.ts +395 -36
  496. package/src/runtime/root/runtime-lane.ts +191 -0
  497. package/src/runtime/root/runtime.ts +160 -29
  498. package/src/runtime/root/scheduled-controller-composition.ts +29 -3
  499. package/src/runtime/root/service-runner.ts +2 -2
  500. package/src/runtime/root/service.ts +126 -44
  501. package/src/runtime/root/status.ts +48 -0
  502. package/src/runtime/root/types.ts +32 -9
  503. package/src/runtime/root/workflow-supervisor-composition.ts +681 -0
  504. package/src/runtime/root/workflow-supervisor-runtime.ts +564 -0
  505. package/src/runtime/root/write-fence.ts +50 -2
  506. package/src/runtime/safe-tooling/google-credential-store.ts +67 -22
  507. package/src/runtime/safe-tooling/google-oauth-broker.ts +25 -7
  508. package/src/runtime/safe-tooling/ios-development.ts +22 -8
  509. package/src/runtime/safe-tooling/job-summary.ts +1 -1
  510. package/src/runtime/safe-tooling/workspace-auth.ts +5 -2
  511. package/src/runtime/shared/atomic-text-file.ts +21 -0
  512. package/src/runtime/shared/bounded-child-supervisor.ts +9 -1
  513. package/src/runtime/shared/json-files.ts +8 -3
  514. package/src/runtime/shared/process-environment.ts +20 -9
  515. package/src/runtime/shared/response-budget.ts +1 -3
  516. package/src/runtime/standalone-recovery/controller-home-migration.ts +16 -24
  517. package/src/runtime/standalone-recovery/core.ts +3792 -417
  518. package/src/runtime/standalone-recovery/entry.ts +507 -45
  519. package/src/runtime/standalone-recovery/installer.ts +262 -148
  520. package/src/runtime/standalone-recovery/mcp-server.ts +29 -193
  521. package/src/runtime/standalone-recovery/operation-lock.ts +12 -2
  522. package/src/runtime/standalone-recovery/performance.ts +54 -16
  523. package/src/runtime/standalone-recovery/release.ts +53 -5
  524. package/src/runtime/standalone-recovery/service-labels.ts +5 -2
  525. package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +5 -2
  526. package/src/runtime/workflow/schedules/browser-probe.ts +17 -6
  527. package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +11 -3
  528. package/src/runtime/workflow/schedules/engine.ts +166 -178
  529. package/src/runtime/workflow/schedules/pending-activation.ts +11 -4
  530. package/src/runtime/workflow/schedules/work-continuation.ts +95 -11
  531. package/src/runtime/workflows/runtime.ts +15 -19
  532. package/src/testing/test-governance.ts +5 -1
  533. package/supervisor/chatgpt-conversation.ts +23 -0
  534. package/supervisor/client.ts +218 -0
  535. package/supervisor/control-plane.ts +963 -0
  536. package/supervisor/entry.ts +15 -0
  537. package/supervisor/forge-validators.ts +147 -0
  538. package/supervisor/index.ts +5 -0
  539. package/supervisor/native-browser-adapter.ts +1151 -0
  540. package/supervisor/native-messaging/host.ts +58 -0
  541. package/supervisor/native-messaging/manifest.ts +26 -0
  542. package/supervisor/native-messaging/protocol.ts +27 -0
  543. package/supervisor/paths.ts +18 -0
  544. package/supervisor/protocol.ts +250 -0
  545. package/supervisor/server.ts +412 -0
  546. package/supervisor/store.ts +1870 -0
  547. package/supervisor/tsconfig.json +8 -0
  548. package/supervisor/types.ts +261 -0
  549. package/SKILL.md +0 -427
  550. package/adapters/chatgpt/controller-host.ts +0 -119
  551. package/adapters/mcp/controller-round-compatibility.ts +0 -184
  552. package/adapters/mcp/frozen-client-semantic-compatibility.ts +0 -292
  553. package/adapters/mcp/runtime-gateway/work-compat-adapter.ts +0 -502
  554. package/adapters/mcp/runtime-gateway/work-validation-reconciler.ts +0 -1
  555. package/adapters/mcp/toolset-selection.ts +0 -41
  556. package/agents/openai.yaml +0 -4
  557. package/assets/skill-hooks.json +0 -41
  558. package/assets/skill-version.json +0 -189
  559. package/assets/skills/claude-review/SKILL.md +0 -231
  560. package/assets/skills/codex-review/SKILL.md +0 -103
  561. package/assets/templates/helpers/check-skill-version.ts +0 -193
  562. package/packages/kernel/progression/api/index.ts +0 -2
  563. package/packages/kernel/progression/application/projector.ts +0 -211
  564. package/packages/kernel/progression/domain/types.ts +0 -116
  565. package/packages/kernel/progression/index.ts +0 -1
  566. package/packages/kernel/scheduler/application/continuation-service.ts +0 -212
  567. package/packages/kernel/scheduler/domain/continuation.ts +0 -38
  568. package/packages/kernel/scheduler/infrastructure/continuation-dispatch-store.ts +0 -38
  569. package/packages/kernel/work/domain/admission-policy.ts +0 -34
  570. package/scripts/benchmark-background-check-overlap.ts +0 -228
  571. package/scripts/benchmark-computer-hotpath.ts +0 -255
  572. package/scripts/benchmark-controller-hotpath.ts +0 -212
  573. package/scripts/benchmark-controller-round2.ts +0 -191
  574. package/scripts/benchmark-ios-agent-device.ts +0 -511
  575. package/scripts/benchmark-mcp-host.sh +0 -117
  576. package/scripts/benchmark-mcp-transport.ts +0 -169
  577. package/scripts/benchmark-operational-memory-activation.ts +0 -235
  578. package/scripts/benchmark-operational-shadow.ts +0 -28
  579. package/scripts/benchmark-quality-harness.ts +0 -146
  580. package/scripts/benchmark-route-session-concurrency.ts +0 -915
  581. package/scripts/benchmark-thin-harness-gateway-ab.ts +0 -632
  582. package/scripts/benchmark-thin-harness-mcp-e2e.ts +0 -498
  583. package/scripts/benchmark-thin-harness.ts +0 -251
  584. package/scripts/benchmark-typescript-navigation.ts +0 -186
  585. package/scripts/benchmark-work-efficiency.ts +0 -334
  586. package/scripts/build-controller-ui.ts +0 -28
  587. package/scripts/check-npm-release.sh +0 -32
  588. package/scripts/check-public-release-surface.sh +0 -19
  589. package/scripts/check-release-published.sh +0 -57
  590. package/scripts/check-release-readiness.sh +0 -37
  591. package/scripts/check-release-version.mjs +0 -74
  592. package/scripts/check-skill-version.ts +0 -5
  593. package/scripts/check-tarball-install-smoke.sh +0 -150
  594. package/scripts/ensure-codegraph.sh +0 -16
  595. package/scripts/package-source-archive.sh +0 -147
  596. package/scripts/public-release-files.txt +0 -39
  597. package/scripts/public-release.ts +0 -174
  598. package/scripts/publish-release-tarball.sh +0 -27
  599. package/scripts/route-nl-vs-ts-eval.ts +0 -679
  600. package/scripts/run-skill-hook.ts +0 -244
  601. package/scripts/stage-runtime-release.ts +0 -44
  602. package/scripts/sync-codex-installed-copies.sh +0 -182
  603. package/src/cli/commands/tools.ts +0 -167
  604. package/src/cli/controller/progress.ts +0 -656
  605. package/src/cli/controller/work-mode.ts +0 -181
  606. package/src/cli/local-bridge/console-assets.ts +0 -17
  607. package/src/cli/local-bridge/dashboard.ts +0 -17
  608. package/src/cli/local-bridge/frontend/src/App.tsx +0 -10
  609. package/src/cli/local-bridge/frontend/src/components/Button.tsx +0 -1
  610. package/src/cli/local-bridge/frontend/src/components/DetailPane.tsx +0 -3
  611. package/src/cli/local-bridge/frontend/src/components/SearchField.tsx +0 -1
  612. package/src/cli/local-bridge/frontend/src/components/SectionHeader.tsx +0 -1
  613. package/src/cli/local-bridge/frontend/src/components/Segmented.tsx +0 -1
  614. package/src/cli/local-bridge/frontend/src/components/StatusText.tsx +0 -3
  615. package/src/cli/local-bridge/frontend/src/design/icons.tsx +0 -11
  616. package/src/cli/local-bridge/frontend/src/design/tokens.css +0 -8
  617. package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +0 -153
  618. package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +0 -37
  619. package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +0 -183
  620. package/src/cli/local-bridge/frontend/src/features/repositories/RepositoriesView.tsx +0 -2
  621. package/src/cli/local-bridge/frontend/src/features/system/SystemView.tsx +0 -2
  622. package/src/cli/local-bridge/frontend/src/features/work/WorkView.tsx +0 -4
  623. package/src/cli/local-bridge/frontend/src/lib/api.ts +0 -30
  624. package/src/cli/local-bridge/frontend/src/lib/format.ts +0 -4
  625. package/src/cli/local-bridge/frontend/src/lib/routes.ts +0 -7
  626. package/src/cli/local-bridge/frontend/src/main.tsx +0 -1
  627. package/src/cli/local-bridge/frontend/src/shell/AppShell.tsx +0 -1
  628. package/src/cli/local-bridge/frontend/src/shell/CommandBar.tsx +0 -2
  629. package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +0 -4
  630. package/src/cli/local-bridge/frontend/src/styles.css +0 -28
  631. package/src/cli/local-bridge/frontend/src/types.ts +0 -15
  632. package/src/cli/local-bridge/frontend/src/vite-env.d.ts +0 -1
  633. package/src/cli/local-bridge/frontend/vite.config.ts +0 -27
  634. package/src/cli/local-bridge/ui-dist/app.css +0 -1
  635. package/src/cli/local-bridge/ui-dist/app.js +0 -11228
  636. package/src/cli/mcp/access-mode.ts +0 -2
  637. package/src/cli/mcp/access-tools.ts +0 -2
  638. package/src/cli/mcp/audit.ts +0 -2
  639. package/src/cli/mcp/auth.ts +0 -2
  640. package/src/cli/mcp/instructions.ts +0 -2
  641. package/src/cli/mcp/legacy-context.ts +0 -2
  642. package/src/cli/mcp/legacy-tool-service.ts +0 -2
  643. package/src/cli/mcp/multi-repository.ts +0 -2
  644. package/src/cli/mcp/oauth.ts +0 -2
  645. package/src/cli/mcp/openai-secure-tunnel.ts +0 -2
  646. package/src/cli/mcp/paths.ts +0 -2
  647. package/src/cli/mcp/policy.ts +0 -2
  648. package/src/cli/mcp/post-finalize-work-attribution.ts +0 -2
  649. package/src/cli/mcp/proxy-env.ts +0 -2
  650. package/src/cli/mcp/readiness-projection.ts +0 -2
  651. package/src/cli/mcp/redaction.ts +0 -2
  652. package/src/cli/mcp/repo.ts +0 -2
  653. package/src/cli/mcp/repository-tools.ts +0 -2
  654. package/src/cli/mcp/server.ts +0 -2
  655. package/src/cli/mcp/setup.ts +0 -2
  656. package/src/cli/mcp/tool-capability-cache.ts +0 -2
  657. package/src/cli/mcp/tool-contract.ts +0 -2
  658. package/src/cli/mcp/tools.ts +0 -2
  659. package/src/cli/mcp/toolset-names.ts +0 -2
  660. package/src/cli/mcp/toolset-selection.ts +0 -2
  661. package/src/cli/mcp/toolset.ts +0 -2
  662. package/src/cli/mcp/transports/http.ts +0 -2
  663. package/src/cli/mcp/transports/session-registry.ts +0 -2
  664. package/src/cli/mcp/transports/stdio.ts +0 -2
  665. package/src/cli/mcp/types.ts +0 -2
  666. package/src/cli/mcp/umbrella-tools.ts +0 -2
  667. package/src/cli/tools/codegraph.ts +0 -695
  668. package/src/core/adoption/helper-wrapper-plan.ts +0 -159
  669. package/src/runtime/context/codegraph-cache-boundary.ts +0 -255
  670. package/src/runtime/context/codegraph-read-provider.ts +0 -611
  671. package/src/runtime/context/codegraph-sidecar.cjs +0 -248
  672. package/src/runtime/control-plane/codegraph-cache-retention.ts +0 -164
  673. package/src/runtime/control-plane/execution/content-equivalent-commit-authority.ts +0 -169
  674. package/src/runtime/control-plane/execution/direct-canonical-work-reconciliation.ts +0 -85
  675. package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +0 -655
  676. package/src/runtime/control-plane/execution/work-finalization-service.ts +0 -2850
  677. package/src/runtime/control-plane/execution/work-path-scope.ts +0 -37
  678. package/src/runtime/control-plane/execution/work-task-receipt.ts +0 -468
  679. package/src/runtime/control-plane/facade/controller-round-relay.ts +0 -3
  680. package/src/runtime/control-plane/facade/work-admission-policy.ts +0 -142
  681. package/src/runtime/control-plane/facade/work-implementation-review.ts +0 -2
  682. package/src/runtime/control-plane/facade/work-state-machine.ts +0 -2
  683. package/src/runtime/control-plane/facade/work-task-projection.ts +0 -66
  684. package/src/runtime/control-plane/routing/index.ts +0 -1
  685. package/src/runtime/control-plane/routing/route-policy.ts +0 -401
  686. package/src/runtime/control-plane/routing/workspace-admission.ts +0 -70
  687. package/src/runtime/gateway/mcp/execution-tools.ts +0 -2
  688. package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +0 -2
  689. package/src/runtime/gateway/mcp/persisted-check-process.ts +0 -2
  690. package/src/runtime/gateway/mcp/process-tools.ts +0 -2
  691. package/src/runtime/gateway/mcp/router.ts +0 -2
  692. package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +0 -2
  693. package/src/runtime/gateway/mcp/runtime-tools.ts +0 -2
  694. package/src/runtime/gateway/mcp/work-validation-reconciler.ts +0 -2
  695. package/src/runtime/plugins/browser-provider-registry.ts +0 -2
@@ -2,36 +2,58 @@ 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
- import { selected } from "./shared-adapter";
8
- import { reconcileReadinessProjectionSource } from "../readiness-projection";
9
- import { listExecutionJobs } from "../../../src/runtime/execution/jobs/store";
7
+ import { selected, selectedOptional } from "./shared-adapter";
8
+ import { SEMANTIC_SCOPE_KEY } from "../../../src/cli/repositories/controller-home";
10
9
  import type { ExecutionJob } from '../../../src/runtime/execution/jobs/types';
11
10
  import { getProcessRecord, isManagedProcessActive, processRuntimeResourceDiagnostics } from "../../../src/runtime/execution/process-runtime";
12
- import { readForgeRuntimeStatus } from "../../../src/runtime/control-plane/runtime-status-client";
13
- import { readSchedulerHealthSnapshot } from "../../../src/runtime/control-plane/global-scheduler/scheduler";
14
- import { evaluateActiveRuntimeSourceDrift, formatRuntimeSourceDriftMessage, readRuntimeGeneration, type RuntimeSourceIdentity } from "../../../src/runtime/control-plane/runtime-generation";
15
- import { projectionObservation, readRepositoryProjectionSnapshot } from "../../../src/runtime/projections/materialized-view";
16
- import { buildRuntimeOperationalView, classifyRuntimeReadinessSemantics, evaluateRuntimeHealth, RUNTIME_HEALTH_THRESHOLDS, type RuntimeOperationalView, type GradedObservation } from "../../../src/runtime/health";
17
- import { buildControllerTaskLedgerProjection } from "../../../src/cli/controller/task-ledger";
18
- import { legacyIssueAuthorityRetired } from "../../../src/cli/controller/legacy-issue-cutover";
11
+ import { formatRuntimeSourceDriftMessage, readRuntimeGeneration } from "../../../src/runtime/control-plane/runtime-generation";
19
12
  import { listControllerChecks } from "../../../src/cli/controller/check-runner";
20
13
  import { buildCheckExecutionSchedule } from "../../../src/runtime/execution/process-runtime/check-scheduling";
21
- import { FORGE_MCP_SCHEMA_VERSION, FORGE_TOOL_SURFACE, FORGE_VERSION } from "../../../src/cli/controller/runtime-config";
22
- import { resolveLocalBridgeSurface } from "../../../src/runtime/shared/local-bridge-surface";
23
14
  import { listAssistantPluginManifests } from "../../../src/runtime/plugins/store";
24
15
  import { cachedGitIdentity, gitSnapshot } from "../../../src/cli/repository/inspector";
25
16
  import { buildRuntimeMaintenanceStatus } from "../../../src/runtime/recovery";
26
- import { allowedFacadeOperations, buildFacadeResult, listCapabilityDescriptors, summarizeCapabilityGroups, listHandoffAttentionItems, listHandoffItems, normalizeCheckIds, buildWorkContinuationSnapshot, listPlanContracts, summarizePlanContract, runHandoffInboxApplication, type FacadeTool } from "../../../src/runtime/control-plane/facade";
17
+ import { allowedFacadeOperations, buildFacadeResult, listCapabilityDescriptors, summarizeCapabilityGroups, listHandoffAttentionItems, normalizeCheckIds, buildWorkContinuationSnapshot, listPlanContracts, summarizePlanContract, runHandoffInboxApplication, type FacadeTool } from "../../../src/runtime/control-plane/facade";
27
18
  import { buildJobOperationDigest } from '../../../src/runtime/control-plane/facade/operation-digest';
28
- 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';
29
21
  import { observeRuntimeStatus } from "../../../src/runtime/root/status";
30
22
  import { getControllerSession } from "../../../packages/kernel/controller/api/index";
23
+ import { listActiveOccurrences, listSchedules, scheduleOwnsWork } from "../../../packages/kernel/scheduler/api/index";
31
24
  import { summarizeHandoffItem } from '../../../src/runtime/control-plane/facade';
32
25
  import type { CallToolResult } from '../../../packages/protocols/mcp/tool-contract';
33
- import { handoffResolvedContinuationEventName, triggerWorkContinuationRepositoryEvent } from '../../../src/runtime/workflow/schedules/work-continuation';
26
+ import { triggerResolvedHandoffContinuation } from '../../../src/runtime/workflow/schedules/work-continuation';
27
+ import { getUserRequest, listUserRequests, recordUserRequest, resolveUserRequest, type UserRequest } from '../../../packages/kernel/identity/api/index';
28
+ import { controllerReadinessEvidence, runtimeSourceSnapshotStatus } from './runtime-readiness-observation';
29
+ import { readRuntimeReleaseAuthority } from '../../../src/runtime/root/release-store';
30
+ import { getWorkflowSupervisorConsumerStatus, getWorkflowSupervisorContinuationProof } from '../../../supervisor/client';
31
+ import { resolveWorkflowSupervisorForgeHome } from '../../../supervisor/paths';
32
+ export { ageMs, probeLocalControllerHealth, localControllerDiagnosticMatchesRuntime, controllerReadinessEvidence, runtimeSourceSnapshotStatus } from './runtime-readiness-observation';
33
+ export type { ControllerReadinessSignals } from './runtime-readiness-observation';
34
34
 
35
+ export const PRIMARY_WORK_RUNTIME_ACTIVITIES = [
36
+ 'running',
37
+ 'waiting_for_user',
38
+ 'scheduled',
39
+ 'recoverable',
40
+ 'needs_reconciliation',
41
+ ] as const;
42
+ export type PrimaryWorkRuntimeActivity = (typeof PRIMARY_WORK_RUNTIME_ACTIVITIES)[number];
43
+
44
+ /** Read-only runtime projection. These facts never mutate or extend semantic Work state. */
45
+ export function primaryWorkRuntimeActivity(facts: {
46
+ running: boolean;
47
+ waitingForUser: boolean;
48
+ scheduled: boolean;
49
+ needsReconciliation: boolean;
50
+ }): PrimaryWorkRuntimeActivity {
51
+ if (facts.running) return 'running';
52
+ if (facts.waitingForUser) return 'waiting_for_user';
53
+ if (facts.scheduled) return 'scheduled';
54
+ if (facts.needsReconciliation) return 'needs_reconciliation';
55
+ return 'recoverable';
56
+ }
35
57
 
36
58
  export const GIT_IDENTITY_SAMPLE_TTL_MS = Math.max(1_000, Number(process.env.FORGE_GIT_IDENTITY_SAMPLE_TTL_MS ?? 3_000));
37
59
 
@@ -79,7 +101,7 @@ export function summarizeWorkListItem(job: ExecutionJob): Record<string, unknown
79
101
  createdAt: job.createdAt,
80
102
  updatedAt: job.updatedAt,
81
103
  suggestedNextAction: digest.suggestedNextActions[0],
82
- detailPointer: { tool: 'work_get', work_id: job.jobId },
104
+ detailPointer: { tool: 'rh_work', operation: 'get', work_id: job.jobId },
83
105
  };
84
106
  }
85
107
 
@@ -103,210 +125,6 @@ export function invalidFacadeOperation(tool: FacadeTool, operation: string): Cal
103
125
  }
104
126
 
105
127
 
106
- export function ageMs(value: string | undefined): number | undefined {
107
- if (!value) return undefined;
108
- const parsed = Date.parse(value);
109
- return Number.isFinite(parsed) ? Math.max(0, Date.now() - parsed) : undefined;
110
- }
111
-
112
- export async function probeLocalControllerHealth(endpoint: string | undefined): Promise<Record<string, unknown> | null> {
113
- if (!endpoint) return null;
114
- const controller = new AbortController();
115
- const timeout = setTimeout(() => controller.abort(), 1_500);
116
- try {
117
- const url = new URL(endpoint);
118
- url.pathname = '/health';
119
- url.search = '';
120
- url.hash = '';
121
- const response = await fetch(url, { signal: controller.signal, headers: { accept: 'application/json' } });
122
- if (!response.ok) return null;
123
- return await response.json() as Record<string, unknown>;
124
- } catch {
125
- return null;
126
- } finally {
127
- clearTimeout(timeout);
128
- }
129
- }
130
-
131
- export function localControllerDiagnosticMatchesRuntime(
132
- payload: Record<string, unknown> | null,
133
- expected: { generation?: string } = {},
134
- ): boolean {
135
- return payload?.status === 'ok'
136
- && payload.toolSurface === FORGE_TOOL_SURFACE
137
- && payload.schemaVersion === FORGE_MCP_SCHEMA_VERSION
138
- && payload.version === FORGE_VERSION
139
- && (expected.generation === undefined || payload.generation === expected.generation);
140
- }
141
-
142
- export interface ControllerReadinessSignals {
143
- externalEndpoint?: GradedObservation;
144
- mcpHandshake?: GradedObservation;
145
- sessionContinuity?: GradedObservation;
146
- }
147
-
148
- export async function controllerReadinessEvidence(
149
- ctx: MultiRepositoryMcpToolContext,
150
- repository = ctx.explicitRepository,
151
- signals: ControllerReadinessSignals = {},
152
- ) {
153
- const daemon = readForgeRuntimeStatus(ctx.controllerHome);
154
- const scheduler = readSchedulerHealthSnapshot(ctx.controllerHome);
155
- const projectionSnapshot = repository ? readRepositoryProjectionSnapshot(ctx.controllerHome, repository.repoId) : undefined;
156
- const projection = projectionSnapshot?.projection;
157
- const taskLedger = repository && !legacyIssueAuthorityRetired(repository.canonicalRoot)
158
- ? buildControllerTaskLedgerProjection(repository.canonicalRoot)
159
- : undefined;
160
- const projectionReconciliation = projectionSnapshot
161
- ? reconcileReadinessProjectionSource(projectionSnapshot, taskLedger)
162
- : undefined;
163
- const localBridgeSurface = repository
164
- ? resolveLocalBridgeSurface({
165
- controllerHome: ctx.controllerHome,
166
- repoRoot: repository.canonicalRoot,
167
- allowProcessScan: false,
168
- })
169
- : undefined;
170
- const localBridgeEndpoint = localBridgeSurface?.endpoint;
171
- const shouldProbeLocalBridge = Boolean(
172
- localBridgeSurface?.enabled
173
- && localBridgeSurface.endpointConfigured
174
- && localBridgeEndpoint
175
- && localBridgeSurface.mode !== 'disabled',
176
- );
177
- const localBridgeLiveHealth = shouldProbeLocalBridge
178
- ? await probeLocalControllerHealth(localBridgeEndpoint)
179
- : null;
180
- const localBridgeEndpointReachable = localBridgeLiveHealth !== null;
181
- const localBridgeExpectedSurface = shouldProbeLocalBridge
182
- ? localControllerDiagnosticMatchesRuntime(localBridgeLiveHealth, {
183
- generation: localBridgeSurface?.generation,
184
- })
185
- : true;
186
- const schedulerHeartbeatAgeMs = ageMs(scheduler.lastTickAt);
187
- const dispatchHeartbeatAgeMs = ageMs(scheduler.lastDispatchAt);
188
- const localBridgeObservation = {
189
- enabled: localBridgeSurface?.enabled ?? false,
190
- requiredForReadiness: localBridgeSurface?.requiredForReadiness ?? false,
191
- mode: localBridgeSurface?.mode ?? ('disabled' as const),
192
- endpoint: localBridgeEndpoint,
193
- endpointReachable: shouldProbeLocalBridge ? localBridgeEndpointReachable : true,
194
- expectedSurface: localBridgeExpectedSurface,
195
- processAlive: localBridgeSurface?.processRunning,
196
- runtimeStateFresh: localBridgeSurface?.source === 'service-runtime'
197
- || localBridgeSurface?.source === 'repo-runtime',
198
- error: localBridgeSurface?.error,
199
- };
200
- const runtimeHealth = evaluateRuntimeHealth({
201
- daemon: {
202
- status: daemon.status,
203
- error: daemon.error,
204
- // Scheduler ticks are emitted by the Canonical Forge Runtime process and provide
205
- // its continuously refreshed heartbeat without introducing a second timer.
206
- heartbeatAgeMs: schedulerHeartbeatAgeMs,
207
- },
208
- scheduler: {
209
- status: daemon.degraded ? 'degraded' : daemon.status,
210
- heartbeatAgeMs: schedulerHeartbeatAgeMs,
211
- dispatchHeartbeatAgeMs,
212
- },
213
- workers: {
214
- queueDepth: projection?.queueDepth,
215
- runningWorkers: projection?.runningWorkers,
216
- activeLeases: projection?.activeLeases,
217
- activeAttentionCount: projection?.currentAttention.length,
218
- },
219
- projection: projectionSnapshot ? projectionObservation(projectionSnapshot, projectionReconciliation) : {
220
- readable: true,
221
- persisted: true,
222
- },
223
- localBridge: localBridgeObservation,
224
- runtimeStorage: { readable: true, ready: true },
225
- ...signals,
226
- });
227
- const operationalView: RuntimeOperationalView = buildRuntimeOperationalView({
228
- health: runtimeHealth,
229
- handoffs: repository
230
- ? listHandoffItems({ controllerHome: ctx.controllerHome, repoId: repository.repoId, status: 'all', limit: 100 })
231
- : [],
232
- jobs: repository ? listExecutionJobs(ctx.controllerHome, repository.repoId, 100) : [],
233
- });
234
- const reasons: Array<{ code: string; message: string }> = runtimeHealth.activeBlockers.map((item) => ({
235
- code: item.code === 'SCHEDULER_NOT_PROGRESSING'
236
- ? 'DISPATCH_LOOP_STALLED'
237
- : item.code === 'LEASE_WITHOUT_WORKER' || item.code === 'WORKER_NOT_RUNNING'
238
- ? 'WORKER_NOT_RUNNING'
239
- : item.code,
240
- message: item.message,
241
- }));
242
- if (
243
- reasons.some((item) => item.code === 'WORKER_NOT_RUNNING')
244
- && (dispatchHeartbeatAgeMs === undefined || dispatchHeartbeatAgeMs > RUNTIME_HEALTH_THRESHOLDS.queueProgressStaleMs)
245
- ) {
246
- reasons.push({
247
- code: 'QUEUE_NOT_PROGRESSING',
248
- message: 'Queued Jobs have not received a recent dispatch heartbeat.',
249
- });
250
- }
251
- const ready = runtimeHealth.ready;
252
- return {
253
- ready,
254
- state: ready ? runtimeHealth.state === 'healthy' ? 'ready' as const : 'degraded' as const : daemon.status === 'ready' ? 'degraded' as const : 'not_ready' as const,
255
- reasons,
256
- warnings: runtimeHealth.warnings.map((item) => ({ code: item.code, message: item.message })),
257
- health: runtimeHealth,
258
- operationalView,
259
- daemon,
260
- durableScheduler: {
261
- status: runtimeHealth.components.scheduler.ready ? 'ready' : daemon.status === 'ready' ? 'degraded' : 'not_ready',
262
- loopStartedAt: scheduler.loopStartedAt,
263
- lastTickAt: scheduler.lastTickAt,
264
- lastDispatchAt: scheduler.lastDispatchAt,
265
- lastReconcileAt: scheduler.lastReconcileAt,
266
- heartbeatAgeMs: schedulerHeartbeatAgeMs,
267
- dispatchHeartbeatAgeMs,
268
- },
269
- workerLoop: {
270
- status: projection?.runningWorkers ? 'running' : projection?.queueDepth ? 'idle' : 'ready',
271
- queueDepth: projection?.queueDepth ?? 0,
272
- runningWorkers: projection?.runningWorkers ?? 0,
273
- activeLeases: projection?.activeLeases ?? 0,
274
- activeAttentionCount: projection?.currentAttention.length ?? 0,
275
- consuming: (projection?.queueDepth ?? 0) === 0 || (projection?.runningWorkers ?? 0) > 0,
276
- },
277
- localBridge: repository ? {
278
- running: Boolean(localBridgeSurface?.enabled)
279
- && runtimeHealth.components.localBridge.ready
280
- && (!shouldProbeLocalBridge || (localBridgeEndpointReachable && localBridgeExpectedSurface)),
281
- endpoint: localBridgeEndpoint,
282
- error: localBridgeSurface?.error,
283
- inferredPid: localBridgeSurface?.pid,
284
- statusSource: localBridgeSurface?.source ?? 'none',
285
- health: runtimeHealth.components.localBridge,
286
- } : undefined,
287
- projection,
288
- projectionSnapshot,
289
- taskLedger,
290
- projectionReconciliation,
291
- semantics: classifyRuntimeReadinessSemantics(runtimeHealth),
292
- };
293
- }
294
-
295
- export function runtimeSourceSnapshotStatus(
296
- active: RuntimeSourceIdentity | undefined,
297
- currentRuntimeRoot?: string,
298
- ) {
299
- const drift = evaluateActiveRuntimeSourceDrift(active, {
300
- currentRuntimeRoot,
301
- });
302
- return {
303
- current: drift.current,
304
- restartRequired: drift.restartRequired,
305
- reasons: drift.reasons,
306
- code: drift.code,
307
- };
308
- }
309
-
310
128
  export function repositoryExecutionReadiness(
311
129
  repoRoot: string,
312
130
  availableChecks: ReturnType<typeof listControllerChecks>,
@@ -406,21 +224,35 @@ export async function callStatusInboxAdapter(
406
224
  ports: StatusInboxAdapterPorts,
407
225
  ): Promise<CallToolResult | undefined> {
408
226
  if (name === 'rh_status') {
409
- const repository = selected(ctx, args);
227
+ const repository = selectedOptional(ctx, args);
410
228
  const operation = String(args.operation ?? 'get');
411
229
  if (!allowedFacadeOperations('rh_status').includes(operation)) {
412
230
  return invalidFacadeOperation('rh_status', operation);
413
231
  }
414
- const store = {
415
- controllerHome: ctx.controllerHome,
416
- repoId: repository.repoId,
417
- revisionContains: (ancestorRevision: string, descendantRevision: string) =>
418
- repositoryRevisionContains(repository.canonicalRoot, ancestorRevision, descendantRevision),
419
- };
232
+ // Instance-level status stays available with zero (or several) registered
233
+ // repositories: only the repository-derived sections need a target.
234
+ const store = repository
235
+ ? {
236
+ controllerHome: ctx.controllerHome,
237
+ repoId: repository.repoId,
238
+ revisionContains: (ancestorRevision: string, descendantRevision: string) =>
239
+ repositoryRevisionContains(repository.canonicalRoot, ancestorRevision, descendantRevision),
240
+ }
241
+ : undefined;
420
242
  if (operation === 'repair') {
243
+ if (!repository) {
244
+ return result(buildFacadeResult({
245
+ status: 'blocked',
246
+ summary: 'REPOSITORY_CONTEXT_REQUIRED_FOR_REPAIR: rh_status repair needs an explicit repository target.',
247
+ data: { operation, repositoryContext: null },
248
+ }) as unknown as Record<string, unknown>, true);
249
+ }
421
250
  return await ports.repair(ctx, repository, args);
422
251
  }
423
- const detailLevel = args.detail_level === 'detail' ? 'detail' : 'summary';
252
+ const requestedDetailLevel = args.detail_level === 'detail' ? 'detail' : 'summary';
253
+ // Repository detail needs a repository; the instance-level summary remains
254
+ // available and reports the downgrade explicitly instead of failing.
255
+ const detailLevel = repository ? requestedDetailLevel : 'summary';
424
256
  if (detailLevel === 'summary') {
425
257
  const startedAt = performance.now();
426
258
  let summaryTimingMark = startedAt;
@@ -435,8 +267,8 @@ export async function callStatusInboxAdapter(
435
267
  // Summary answers only whether this repository can work now. Reuse one
436
268
  // porcelain-v2 sample for branch/HEAD/dirty and avoid the full Git
437
269
  // status/diff-stat, access-policy, and inventory construction paths.
438
- const repositoryIdentity = cachedGitIdentity(repository.canonicalRoot);
439
- const repositoryIdentityAgeMs = Math.max(0, Date.now() - repositoryIdentity.sampledAt);
270
+ const repositoryIdentity = repository ? cachedGitIdentity(repository.canonicalRoot) : undefined;
271
+ const repositoryIdentityAgeMs = repositoryIdentity ? Math.max(0, Date.now() - repositoryIdentity.sampledAt) : undefined;
440
272
  markSummaryPhase('git');
441
273
  const runtimeGeneration = readRuntimeGeneration(ctx.controllerHome);
442
274
  const runtimeSource = runtimeSourceSnapshotStatus(
@@ -457,29 +289,39 @@ export async function callStatusInboxAdapter(
457
289
  : 'RUNTIME_SOURCE_SNAPSHOT_STALE');
458
290
  const runtimeReadiness = observation.snapshot?.readiness;
459
291
  const releaseDiagnostic = runtimeReadiness?.diagnostics.releaseCoherence;
460
- const activeWorkProjection = readActiveWorkCandidates({ ...store, limit: 3 });
292
+ const activeWorkProjection = repository && store
293
+ ? readActiveWorkCandidates({ ...store, limit: 3 })
294
+ : { contracts: [], invalid: [] };
461
295
  const activeWorkSnapshot = activeWorkProjection.contracts.map((entry) => ({
462
296
  workId: entry.workId,
463
- status: entry.status,
464
- mode: entry.mode,
297
+ state: entry.semanticState,
465
298
  objective: entry.objective.slice(0, 160),
466
299
  semantics: buildWorkContinuationSnapshot(entry).semantics,
467
300
  nextSafeAction: buildWorkContinuationSnapshot(entry).nextSafeAction,
468
301
  }));
469
- const activePlanSnapshot = listPlanContracts({ ...store, status: 'active', limit: 3 }).map(summarizePlanContract);
470
- const pendingHandoffAttention = listHandoffAttentionItems(store, 100);
302
+ // Plans are authored semantic context: without a repository target the
303
+ // instance-level semantic scope carries them.
304
+ const activePlanSnapshot = (repository && store
305
+ ? listPlanContracts({ ...store, status: 'active', limit: 3 })
306
+ : listPlanContracts({ controllerHome: ctx.controllerHome, scopeKey: SEMANTIC_SCOPE_KEY, status: 'active', limit: 3 })
307
+ ).map(summarizePlanContract);
308
+ const pendingHandoffAttention = store ? listHandoffAttentionItems(store, 100) : [];
471
309
  const pendingHandoffSnapshot = pendingHandoffAttention.slice(0, 4);
472
310
  const pendingHandoffCount = pendingHandoffAttention.length;
473
311
  markSummaryPhase('controller_state');
474
- const preferredFacadeTools = ['rh_access', 'rh_status', 'rh_inbox', 'rh_context', 'rh_work'] as const;
312
+ const preferredFacadeTools = ['rh_access', 'rh_status', 'rh_inbox', 'rh_context', 'rh_work', 'capability_execute'] as const;
475
313
  const facade = buildFacadeResult({
476
314
  status: ready ? 'ok' : 'blocked',
477
315
  summary: ready ? 'Controller and MCP tool surface are ready for bounded work.' : 'Controller or MCP tool surface needs attention before work.',
478
316
  data: {
479
317
  operation,
480
- repoId: repository.repoId,
318
+ ...(repository ? { repoId: repository.repoId } : {}),
319
+ /** Null means this answer is ForgeInstance-scoped, not repository-scoped. */
320
+ repositoryContext: repository ? { repoId: repository.repoId, checkoutId: repository.activeCheckoutId } : null,
321
+ requestedDetailLevel,
481
322
  readiness: {
482
323
  ready,
324
+ readyFor: 'bounded_execution',
483
325
  reasonCodes: [...new Set(reasonCodes)],
484
326
  diagnostics: {
485
327
  runtime: { ready: observation.ready },
@@ -503,6 +345,11 @@ export async function callStatusInboxAdapter(
503
345
  },
504
346
  semantics: {
505
347
  executionReady: observation.ready,
348
+ // Summary is intentionally the cheap Runtime snapshot path. It
349
+ // reports bounded execution readiness without pretending that the
350
+ // full scheduler/worker diagnostics for unattended continuation ran.
351
+ autonomousContinuationReady: null,
352
+ autonomousContinuationBlockers: null,
506
353
  maintenanceHealthy: null,
507
354
  maintenanceCandidateCount: 0,
508
355
  releaseReady: releaseDiagnostic?.outcome === 'pass',
@@ -513,21 +360,23 @@ export async function callStatusInboxAdapter(
513
360
  },
514
361
  observedAt: observation.observedAt,
515
362
  },
516
- repositoryState: {
517
- branch: repositoryIdentity.branch,
518
- head: repositoryIdentity.head,
519
- dirty: repositoryIdentity.dirty,
520
- observedAt: new Date(repositoryIdentity.sampledAt).toISOString(),
521
- observationAgeMs: repositoryIdentityAgeMs,
522
- observationMaxAgeMs: GIT_IDENTITY_SAMPLE_TTL_MS,
523
- observationPolicy: 'bounded_sample_with_mutation_invalidation',
524
- sourceSnapshotAgeMs: runtimeGeneration?.source.observedAt
525
- ? Math.max(0, Date.now() - Date.parse(runtimeGeneration.source.observedAt))
526
- : undefined,
527
- sourceSnapshotStale,
528
- sourceSnapshotReasons: runtimeSource.reasons,
529
- runtimeSourceDirty: runtimeSource.current?.dirty === true,
530
- },
363
+ repositoryState: repositoryIdentity
364
+ ? {
365
+ branch: repositoryIdentity.branch,
366
+ head: repositoryIdentity.head,
367
+ dirty: repositoryIdentity.dirty,
368
+ observedAt: new Date(repositoryIdentity.sampledAt).toISOString(),
369
+ observationAgeMs: repositoryIdentityAgeMs,
370
+ observationMaxAgeMs: GIT_IDENTITY_SAMPLE_TTL_MS,
371
+ observationPolicy: 'bounded_sample_with_mutation_invalidation',
372
+ sourceSnapshotAgeMs: runtimeGeneration?.source.observedAt
373
+ ? Math.max(0, Date.now() - Date.parse(runtimeGeneration.source.observedAt))
374
+ : undefined,
375
+ sourceSnapshotStale,
376
+ sourceSnapshotReasons: runtimeSource.reasons,
377
+ runtimeSourceDirty: runtimeSource.current?.dirty === true,
378
+ }
379
+ : null,
531
380
  toolArchitecture: {
532
381
  facadeTools: [...preferredFacadeTools],
533
382
  domainSchemaLoading: 'status_summary_runtime_snapshot',
@@ -581,6 +430,15 @@ export async function callStatusInboxAdapter(
581
430
  (payload.responseMeta as { structuredPayloadBytes: number }).structuredPayloadBytes = Buffer.byteLength(JSON.stringify(payload), 'utf8');
582
431
  return result(payload, facade.status !== 'ok');
583
432
  }
433
+ // Detail is repository-derived; without a repository target the requested
434
+ // detail level was already downgraded to the instance-level summary above.
435
+ if (!repository || !store) {
436
+ return result(buildFacadeResult({
437
+ status: 'blocked',
438
+ summary: 'REPOSITORY_CONTEXT_REQUIRED_FOR_DETAIL: rh_status detail needs an explicit repository target.',
439
+ data: { operation, repositoryContext: null },
440
+ }) as unknown as Record<string, unknown>, true);
441
+ }
584
442
  const detailTimingStartedAt = performance.now();
585
443
  let detailTimingMark = detailTimingStartedAt;
586
444
  const detailPhaseTimingsMs: Record<string, number> = {};
@@ -590,6 +448,7 @@ export async function callStatusInboxAdapter(
590
448
  detailTimingMark = now;
591
449
  };
592
450
  const readiness = await controllerReadinessEvidence(ctx, repository);
451
+ const runtimeObservation = observeRuntimeStatus(ctx.controllerHome);
593
452
  markDetailPhase('readiness');
594
453
  const liveGit = gitSnapshot(repository.canonicalRoot);
595
454
  markDetailPhase('git');
@@ -598,7 +457,7 @@ export async function callStatusInboxAdapter(
598
457
  const runtimeSource = runtimeSourceSnapshotStatus(readiness.daemon.source, ctx.runtimeSourceRoot);
599
458
  const sourceSnapshotStale = runtimeSource.restartRequired;
600
459
  const exposure = controllerExposureSnapshot(ctx);
601
- const localRegisteredToolNames = allControllerToolDefinitions(ctx).map((tool) => tool.name).sort();
460
+ const localRegisteredToolNames = [...exposure.actualToolNames].sort();
602
461
  markDetailPhase('tool_surface');
603
462
  const toolSurfaceReady = exposure.ready && exposure.missingToolNames.length === 0;
604
463
  // Ordinary interactive execution depends on the execution axis only.
@@ -647,8 +506,77 @@ export async function callStatusInboxAdapter(
647
506
  });
648
507
  }
649
508
  const toolSurfaceComputed = exposure.expectedToolNames.length > 0 || exposure.actualToolNames.length > 0 || toolSurfaceReady;
509
+ const activeReleaseAuthority = readRuntimeReleaseAuthority(ctx.controllerHome);
510
+ let autonomousContinuationProof: Awaited<ReturnType<typeof getWorkflowSupervisorContinuationProof>>;
511
+ let autonomousContinuationProofObservation: 'proven' | 'missing' | 'unavailable' = 'missing';
512
+ if (activeReleaseAuthority?.committedAt) {
513
+ try {
514
+ autonomousContinuationProof = await getWorkflowSupervisorContinuationProof(
515
+ resolveWorkflowSupervisorForgeHome(ctx.controllerHome),
516
+ {
517
+ repoId: repository.repoId,
518
+ activeReleaseId: activeReleaseAuthority.active.releaseId,
519
+ notBefore: activeReleaseAuthority.committedAt,
520
+ },
521
+ );
522
+ autonomousContinuationProofObservation = autonomousContinuationProof ? 'proven' : 'missing';
523
+ } catch {
524
+ autonomousContinuationProofObservation = 'unavailable';
525
+ }
526
+ }
527
+ let autonomousContinuationConsumerStatus: Awaited<ReturnType<typeof getWorkflowSupervisorConsumerStatus>> | undefined;
528
+ let autonomousContinuationConsumerObservation: 'observed' | 'unavailable' = 'unavailable';
529
+ try {
530
+ autonomousContinuationConsumerStatus = await getWorkflowSupervisorConsumerStatus(
531
+ resolveWorkflowSupervisorForgeHome(ctx.controllerHome),
532
+ );
533
+ autonomousContinuationConsumerObservation = 'observed';
534
+ } catch {
535
+ autonomousContinuationConsumerObservation = 'unavailable';
536
+ }
537
+ const dueConsumerFailure = Boolean(
538
+ autonomousContinuationConsumerStatus?.dueCommand
539
+ && autonomousContinuationConsumerStatus.lastFailure
540
+ && (!autonomousContinuationConsumerStatus.lastFailure.effectId
541
+ || autonomousContinuationConsumerStatus.lastFailure.effectId === autonomousContinuationConsumerStatus.dueCommand.effectId),
542
+ );
543
+ const autonomousContinuationConsumerReady = autonomousContinuationConsumerObservation === 'observed'
544
+ && autonomousContinuationConsumerStatus?.enabled === true
545
+ && autonomousContinuationConsumerStatus.running === true
546
+ && autonomousContinuationConsumerStatus.lastTickStartedAt !== undefined
547
+ && autonomousContinuationConsumerStatus.stalled === false
548
+ && !dueConsumerFailure;
549
+ const autonomousContinuationReady = readiness.ready
550
+ && toolSurfaceReady
551
+ && !sourceSnapshotStale
552
+ && autonomousContinuationProofObservation === 'proven'
553
+ && autonomousContinuationConsumerReady;
554
+ const autonomousContinuationBlockers = [...new Set([
555
+ ...readinessReasons
556
+ .map((reason) => reason.code)
557
+ .filter((code): code is string => typeof code === 'string' && code.length > 0),
558
+ ...(autonomousContinuationProofObservation === 'proven'
559
+ ? []
560
+ : [autonomousContinuationProofObservation === 'unavailable'
561
+ ? 'AUTONOMOUS_CONTINUATION_LIVE_PROOF_UNAVAILABLE'
562
+ : 'AUTONOMOUS_CONTINUATION_LIVE_PROOF_MISSING']),
563
+ ...(autonomousContinuationConsumerObservation === 'unavailable'
564
+ ? ['AUTONOMOUS_CONTINUATION_CONSUMER_STATUS_UNAVAILABLE']
565
+ : autonomousContinuationConsumerStatus?.enabled !== true
566
+ ? ['AUTONOMOUS_CONTINUATION_CONSUMER_DISABLED']
567
+ : autonomousContinuationConsumerStatus.running !== true
568
+ ? ['AUTONOMOUS_CONTINUATION_CONSUMER_NOT_RUNNING']
569
+ : autonomousContinuationConsumerStatus.lastTickStartedAt === undefined
570
+ ? ['AUTONOMOUS_CONTINUATION_CONSUMER_NOT_OBSERVED']
571
+ : autonomousContinuationConsumerStatus.stalled
572
+ ? ['AUTONOMOUS_CONTINUATION_CONSUMER_STALLED']
573
+ : dueConsumerFailure
574
+ ? ['AUTONOMOUS_CONTINUATION_CONSUMER_DEGRADED']
575
+ : []),
576
+ ])];
650
577
  const readinessWithToolSurface = {
651
578
  ready: effectiveReady,
579
+ readyFor: 'bounded_execution' as const,
652
580
  reasonCodes: [...new Set(
653
581
  readinessReasons
654
582
  .map((reason) => reason.code)
@@ -656,7 +584,7 @@ export async function callStatusInboxAdapter(
656
584
  )],
657
585
  diagnostics: {
658
586
  runtime: {
659
- ready: readiness.ready,
587
+ ready: runtimeObservation.ready,
660
588
  },
661
589
  toolSurface: {
662
590
  ready: toolSurfaceReady,
@@ -672,6 +600,22 @@ export async function callStatusInboxAdapter(
672
600
  },
673
601
  semantics: {
674
602
  executionReady,
603
+ // Runtime/tool health is necessary but not sufficient. Thin acceptance
604
+ // requires a fresh exact-active-release Supervisor ledger proof of
605
+ // CONTINUE -> CONTINUE -> DONE spanning at least one Runtime reconnect.
606
+ autonomousContinuationReady,
607
+ autonomousContinuationBlockers,
608
+ autonomousContinuationConsumer: {
609
+ observation: autonomousContinuationConsumerObservation,
610
+ ...(autonomousContinuationConsumerStatus ? { status: autonomousContinuationConsumerStatus } : {}),
611
+ },
612
+ autonomousContinuationProof: {
613
+ observation: autonomousContinuationProofObservation,
614
+ activeReleaseId: activeReleaseAuthority?.active.releaseId,
615
+ activeReleaseAuthorityRevision: activeReleaseAuthority?.revision,
616
+ activeReleaseCommittedAt: activeReleaseAuthority?.committedAt,
617
+ ...(autonomousContinuationProof ? { proof: autonomousContinuationProof } : {}),
618
+ },
675
619
  maintenanceHealthy,
676
620
  maintenanceCandidateCount,
677
621
  maintenanceObservation,
@@ -702,6 +646,39 @@ export async function callStatusInboxAdapter(
702
646
  const pendingHandoffCount = pendingHandoffAttention.length;
703
647
  const activeWorkProjection = readActiveWorkCandidates({ ...store, limit: 200 });
704
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.';
705
682
  markDetailPhase('work_state');
706
683
  const activePrimaryWork = activeContracts.filter((contract) => (contract.lifecycleRole ?? 'primary') === 'primary');
707
684
  const activeExecutionChildren = activeContracts.filter((contract) => contract.lifecycleRole === 'execution_child');
@@ -712,14 +689,62 @@ export async function callStatusInboxAdapter(
712
689
  .map((processId) => getProcessRecord(ctx.controllerHome, repository.repoId, processId))
713
690
  .filter((process): process is NonNullable<typeof process> => Boolean(process && isManagedProcessActive(process)));
714
691
  markDetailPhase('process_state');
715
- const activeProcessWorkIds = new Set(activeProcessRecords.map((process) => process.workId).filter((workId): workId is string => Boolean(workId)));
716
- const activeControllerWorkIds = new Set(activePrimaryWork.filter((contract) => Boolean(getControllerSession({ controllerHome: ctx.controllerHome, repoId: repository.repoId }, contract.workId))).map((contract) => contract.workId));
717
- const executingPrimaryWorkIds = new Set([...activeProcessWorkIds, ...activeControllerWorkIds].filter((workId) => activePrimaryWork.some((contract) => contract.workId === workId)));
692
+ const activePrimaryWorkIds = new Set(activePrimaryWork.map((contract) => contract.workId));
693
+ const activeProcessWorkIds = new Set(
694
+ activeProcessRecords
695
+ .map((process) => process.workId)
696
+ .filter((workId): workId is string => Boolean(workId && activePrimaryWorkIds.has(workId))),
697
+ );
698
+ const activeControllerWorkIds = new Set(
699
+ activePrimaryWork
700
+ .filter((contract) => Boolean(getControllerSession({ controllerHome: ctx.controllerHome, repoId: repository.repoId }, contract.workId)))
701
+ .map((contract) => contract.workId),
702
+ );
703
+ const runningPrimaryWorkIds = new Set([...activeProcessWorkIds, ...activeControllerWorkIds]);
718
704
  markDetailPhase('controller_sessions');
719
- const preferredFacadeTools = ['rh_access', 'rh_status', 'rh_inbox', 'rh_context', 'rh_work'] as const;
705
+
706
+ const waitingForUserPrimaryWorkIds = new Set(
707
+ pendingHandoffAttention
708
+ .map((item) => item.workId?.trim())
709
+ .filter((workId): workId is string => Boolean(workId && activePrimaryWorkIds.has(workId))),
710
+ );
711
+ const schedules = listSchedules(ctx.controllerHome, repository.repoId);
712
+ const activeOccurrenceScheduleIds = new Set(
713
+ listActiveOccurrences(ctx.controllerHome, repository.repoId).map((occurrence) => occurrence.scheduleId),
714
+ );
715
+ const scheduledPrimaryWorkIds = new Set<string>();
716
+ for (const schedule of schedules) {
717
+ if (!schedule.enabled && !activeOccurrenceScheduleIds.has(schedule.scheduleId)) continue;
718
+ for (const workId of activePrimaryWorkIds) {
719
+ if (scheduleOwnsWork(schedule, workId)) scheduledPrimaryWorkIds.add(workId);
720
+ }
721
+ }
722
+ const primaryWorkActivities = activePrimaryWork.map((contract) => ({
723
+ workId: contract.workId,
724
+ activity: primaryWorkRuntimeActivity({
725
+ running: runningPrimaryWorkIds.has(contract.workId),
726
+ waitingForUser: waitingForUserPrimaryWorkIds.has(contract.workId),
727
+ scheduled: scheduledPrimaryWorkIds.has(contract.workId),
728
+ needsReconciliation: buildWorkContinuationSnapshot(contract).reconciliationRequired,
729
+ }),
730
+ }));
731
+ const primaryWorkActivityCounts: Record<PrimaryWorkRuntimeActivity, number> = {
732
+ running: 0,
733
+ waiting_for_user: 0,
734
+ scheduled: 0,
735
+ recoverable: 0,
736
+ needs_reconciliation: 0,
737
+ };
738
+ for (const projection of primaryWorkActivities) primaryWorkActivityCounts[projection.activity] += 1;
739
+ markDetailPhase('work_activity');
740
+ const preferredFacadeTools = ['rh_access', 'rh_status', 'rh_inbox', 'rh_context', 'rh_work', 'capability_execute'] as const;
720
741
  const facade = buildFacadeResult({
721
742
  status: effectiveReady ? 'ok' : 'blocked',
722
- summary: effectiveReady ? 'Controller and MCP tool surface are ready for bounded work.' : 'Controller or MCP tool surface needs attention before work.',
743
+ summary: effectiveReady
744
+ ? autonomousContinuationReady
745
+ ? 'Controller and MCP tool surface are ready for bounded work and autonomous continuation.'
746
+ : 'Controller and MCP tool surface are ready for bounded work; autonomous continuation needs attention.'
747
+ : 'Controller or MCP tool surface needs attention before bounded work.',
723
748
  data: {
724
749
  operation,
725
750
  repoId: repository.repoId,
@@ -750,9 +775,28 @@ export async function callStatusInboxAdapter(
750
775
  activePrimaryWorkCount: activePrimaryWork.length,
751
776
  activeExecutionChildCount: activeExecutionChildren.length,
752
777
  activeProcessCount: activeProcessRecords.length,
753
- executingPrimaryWorkCount: executingPrimaryWorkIds.size,
754
- waitingPrimaryWorkCount: Math.max(0, activePrimaryWork.length - executingPrimaryWorkIds.size),
778
+ primaryWorkActivityCounts,
779
+ primaryWorkActivities,
755
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
+ } } : {}),
756
800
  invalidActiveContractCount: activeWorkProjection.invalid.length,
757
801
  invalidActiveContracts: activeWorkProjection.invalid.slice(0, 10).map(summarizeInvalidActiveWorkCandidate),
758
802
  // Summary keeps the stable facade surface only; detail expands to the full registered schema.
@@ -792,10 +836,118 @@ export async function callStatusInboxAdapter(
792
836
  return undefined;
793
837
  }
794
838
 
839
+ function summarizeUserRequest(request: UserRequest) {
840
+ return {
841
+ requestId: request.requestId,
842
+ kind: request.kind,
843
+ title: request.title,
844
+ summary: request.summary,
845
+ actionRequired: request.actionRequired,
846
+ status: request.status,
847
+ targetScope: request.targetScope,
848
+ resolution: request.resolution,
849
+ updatedAt: request.updatedAt,
850
+ };
851
+ }
852
+
853
+ // `request_id` is Process Runtime idempotency/correlation only. UserRequest
854
+ // selection stays on `handoff_id` so retry identity can never change Inbox semantics.
855
+ export function findCanonicalUserRequest(controllerHome: string, args: Record<string, unknown>): UserRequest | undefined {
856
+ const handoffId = typeof args.handoff_id === 'string' ? args.handoff_id.trim() : '';
857
+ if (!handoffId) return undefined;
858
+ return getUserRequest(controllerHome, handoffId)
859
+ ?? listUserRequests(controllerHome, 'all').find((request) => request.presentation?.legacyHandoffId === handoffId);
860
+ }
861
+
862
+ export function shouldUseCanonicalUserRequestInbox(
863
+ repositoryRepoId: string | undefined,
864
+ operation: string,
865
+ request: UserRequest | undefined,
866
+ ): boolean {
867
+ if (!repositoryRepoId) return true;
868
+ if (operation === 'list' || operation === 'create') return false;
869
+ return Boolean(request && !request.targetScope?.repoId?.trim());
870
+ }
871
+
872
+ function callCanonicalUserRequestInbox(ctx: MultiRepositoryMcpToolContext, args: Record<string, unknown>, operation: string): CallToolResult {
873
+ const limit = Math.max(1, Math.min(Math.trunc(typeof args.limit === 'number' ? args.limit : 50), 100));
874
+ if (operation === 'list') {
875
+ const items = listUserRequests(ctx.controllerHome, 'pending').slice(0, limit);
876
+ return result(buildFacadeResult({
877
+ summary: items.length ? `${items.length} pending UserRequest item(s).` : 'No pending UserRequest items.',
878
+ data: { items: items.map(summarizeUserRequest) },
879
+ suggestedNextActions: items.slice(0, 1).map((item) => ({ label: `Read ${item.requestId}`, tool: 'rh_inbox', operation: 'get', payload: { handoff_id: item.requestId }, risk: 'readonly' as const })),
880
+ }) as unknown as Record<string, unknown>);
881
+ }
882
+ if (operation === 'create') {
883
+ const title = typeof args.title === 'string' ? args.title.trim() : '';
884
+ const summary = typeof args.summary === 'string' ? args.summary.trim() : typeof args.reason === 'string' ? args.reason.trim() : '';
885
+ if (!title || !summary) throw new Error('USER_REQUEST_TITLE_SUMMARY_REQUIRED');
886
+ const workId = typeof args.work_id === 'string' ? args.work_id.trim() : '';
887
+ const explicitId = typeof args.handoff_id === 'string' ? args.handoff_id.trim() : '';
888
+ const actionRequired = (typeof args.action_required === 'string' ? args.action_required : 'product_decision') as 'login' | 'grant_permission' | 'confirm_destructive' | 'product_decision';
889
+ const kind = (typeof args.request_kind === 'string' ? args.request_kind : actionRequired === 'product_decision' ? 'user_decision_request' : 'user_action_request') as 'user_action_request' | 'user_decision_request';
890
+ const rootCauseKey = typeof args.root_cause_key === 'string' && args.root_cause_key.trim()
891
+ ? args.root_cause_key.trim()
892
+ : `rh_inbox:${explicitId || workId || title}:${summary}`;
893
+ const item = recordUserRequest(ctx.controllerHome, {
894
+ ...(explicitId ? { requestId: explicitId } : {}),
895
+ kind,
896
+ rootCauseKey,
897
+ title,
898
+ summary,
899
+ actionRequired,
900
+ ...(workId ? { targetScope: { scopeKind: 'work', scopeId: workId, workId } } : {}),
901
+ presentation: {
902
+ ...(typeof args.handoff_id === 'string' && args.handoff_id.trim() ? { legacyHandoffId: args.handoff_id.trim() } : {}),
903
+ ...(typeof args.reason === 'string' ? { reason: args.reason } : {}),
904
+ ...(typeof args.recommended_decision === 'string' ? { recommendedDecision: args.recommended_decision } : {}),
905
+ ...(typeof args.recommended_prompt === 'string' ? { recommendedPrompt: args.recommended_prompt } : {}),
906
+ },
907
+ });
908
+ return result(buildFacadeResult({ summary: `Created UserRequest ${item.requestId}.`, data: { item: summarizeUserRequest(item) } }) as unknown as Record<string, unknown>);
909
+ }
910
+ const current = findCanonicalUserRequest(ctx.controllerHome, args);
911
+ if (operation === 'get') {
912
+ const facade = buildFacadeResult({
913
+ status: current ? 'ok' : 'not_found',
914
+ summary: current ? `UserRequest ${current.requestId}.` : 'UserRequest not found.',
915
+ data: { item: current ? summarizeUserRequest(current) : undefined },
916
+ suggestedNextActions: current?.status === 'pending' ? [{ label: 'Resolve request', tool: 'rh_inbox', operation: 'resolve', payload: { request_id: current.requestId }, risk: 'workspace_write' }] : [],
917
+ });
918
+ return result(facade as unknown as Record<string, unknown>, facade.status === 'not_found');
919
+ }
920
+ if (!current) throw new Error('USER_REQUEST_NOT_FOUND');
921
+ if (operation === 'ack' || operation === 'accept') {
922
+ return result(buildFacadeResult({
923
+ summary: `${operation === 'accept' ? 'Accepted' : 'Acknowledged'} UserRequest ${current.requestId}; semantic state remains pending until resolve/dismiss.`,
924
+ data: { item: summarizeUserRequest(current), compatibilityNoop: true },
925
+ }) as unknown as Record<string, unknown>);
926
+ }
927
+ if (operation === 'resolve' || operation === 'dismiss') {
928
+ const decision = operation === 'dismiss'
929
+ ? (typeof args.decision === 'string' && args.decision.trim() ? args.decision.trim() : 'dismissed')
930
+ : (typeof args.decision === 'string' ? args.decision.trim() : '');
931
+ if (!decision) throw new Error('USER_REQUEST_DECISION_REQUIRED');
932
+ const resolved = resolveUserRequest(ctx.controllerHome, {
933
+ requestId: current.requestId,
934
+ decision,
935
+ resolvedBy: typeof args.resolver === 'string' && args.resolver.trim() ? args.resolver.trim() : (ctx.principalId?.trim() || 'mcp-user'),
936
+ });
937
+ return result(buildFacadeResult({ summary: `Resolved UserRequest ${resolved.requestId}.`, data: { item: summarizeUserRequest(resolved) } }) as unknown as Record<string, unknown>);
938
+ }
939
+ throw new Error(`USER_REQUEST_OPERATION_UNSUPPORTED:${operation}`);
940
+ }
941
+
795
942
  async function callInboxAdapter(ctx: MultiRepositoryMcpToolContext, args: Record<string, unknown>): Promise<CallToolResult> {
796
- const repository = selected(ctx, args);
943
+ const repository = selectedOptional(ctx, args);
797
944
  const operation = String(args.operation ?? 'list');
798
945
  if (!allowedFacadeOperations('rh_inbox').includes(operation)) return invalidFacadeOperation('rh_inbox', operation);
946
+ const canonicalRequest = findCanonicalUserRequest(ctx.controllerHome, args);
947
+ if (shouldUseCanonicalUserRequestInbox(repository?.repoId, operation, canonicalRequest)) {
948
+ return callCanonicalUserRequestInbox(ctx, args, operation);
949
+ }
950
+ if (!repository) throw new Error('REPOSITORY_CONTEXT_REQUIRED_FOR_HANDOFF');
799
951
  const app = await runHandoffInboxApplication({
800
952
  operation: operation as 'get' | 'list' | 'ack' | 'accept' | 'resolve' | 'dismiss' | 'create',
801
953
  store: { controllerHome: ctx.controllerHome, repoId: repository.repoId },
@@ -814,13 +966,7 @@ async function callInboxAdapter(ctx: MultiRepositoryMcpToolContext, args: Record
814
966
  resolver: typeof args.resolver === 'string' ? args.resolver : undefined,
815
967
  controllerIdentity: { principalId: ctx.principalId, sessionId: ctx.sessionId },
816
968
  }, {
817
- triggerResolvedContinuation: (item) => triggerWorkContinuationRepositoryEvent(
818
- ctx.controllerHome,
819
- repository.repoId,
820
- handoffResolvedContinuationEventName(item.id),
821
- `handoff:${item.id}:${item.updatedAt}`,
822
- { workId: item.workId, data: { handoffId: item.id, status: item.status, decision: item.decision } },
823
- ),
969
+ triggerResolvedContinuation: (item) => triggerResolvedHandoffContinuation(ctx.controllerHome, repository.repoId, item),
824
970
  });
825
971
  if (operation === 'get') {
826
972
  const item = 'item' in app ? app.item : undefined;