@moretea-labs/forge 1.8.0 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (528) hide show
  1. package/AGENTS.md +70 -7
  2. package/CHANGELOG.md +14 -0
  3. package/CLAUDE.md +17 -2
  4. package/CONTRIBUTING.md +3 -2
  5. package/THIRD_PARTY_NOTICES.md +1 -1
  6. package/adapters/chatgpt/browser-delivery-host.ts +7 -1
  7. package/adapters/chatgpt/browser-delivery-runtime.ts +529 -56
  8. package/adapters/chatgpt/controller-binding-store.ts +101 -22
  9. package/adapters/chatgpt/controller-round-host.ts +15 -25
  10. package/adapters/chatgpt/controller-round-settlement-store.ts +58 -4
  11. package/adapters/chatgpt/provider-delivery.ts +228 -1
  12. package/adapters/chatgpt/work-conversation-binding-store.ts +79 -53
  13. package/adapters/computer/chatgpt-extension-target.ts +463 -0
  14. package/adapters/computer/chatgpt-target-router.ts +103 -0
  15. package/adapters/computer/chrome-extension/background.js +385 -0
  16. package/adapters/computer/chrome-extension/content.js +378 -0
  17. package/adapters/computer/chrome-extension/core.js +24 -0
  18. package/adapters/computer/chrome-extension/manifest.json +30 -0
  19. package/adapters/computer/desktop-operator-discovery.ts +11 -31
  20. package/adapters/computer/interaction-target-authority.ts +142 -18
  21. package/adapters/mcp/auth.ts +0 -1
  22. package/adapters/mcp/instructions.ts +5 -4
  23. package/adapters/mcp/multi-repository.ts +3 -19
  24. package/adapters/mcp/oauth.ts +73 -0
  25. package/adapters/mcp/paths.ts +4 -1
  26. package/adapters/mcp/runtime-gateway/automation-receipt-adapter.ts +87 -0
  27. package/adapters/mcp/runtime-gateway/bounded-result-runtime.ts +62 -0
  28. package/adapters/mcp/runtime-gateway/cognition-settlement.ts +201 -0
  29. package/adapters/mcp/runtime-gateway/context-adapter.ts +411 -73
  30. package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +91 -0
  31. package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +20 -5
  32. package/adapters/mcp/runtime-gateway/core-capability-adapter.ts +258 -0
  33. package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +10 -27
  34. package/adapters/mcp/runtime-gateway/engineering-tool-contract.ts +15 -0
  35. package/adapters/mcp/runtime-gateway/execution-tools.ts +8 -42
  36. package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +2 -1
  37. package/adapters/mcp/runtime-gateway/plugin-adapter.ts +117 -45
  38. package/adapters/mcp/runtime-gateway/process-tools.ts +190 -22
  39. package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +16 -4
  40. package/adapters/mcp/runtime-gateway/recovery-adapter.ts +69 -52
  41. package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +4 -35
  42. package/adapters/mcp/runtime-gateway/result-adapter.ts +10 -4
  43. package/adapters/mcp/runtime-gateway/router.ts +18 -504
  44. package/adapters/mcp/runtime-gateway/routing-policy.ts +499 -0
  45. package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +14 -65
  46. package/adapters/mcp/runtime-gateway/runtime-readiness-observation.ts +218 -0
  47. package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +113 -173
  48. package/adapters/mcp/runtime-gateway/runtime-tools.ts +15 -5
  49. package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +1 -0
  50. package/adapters/mcp/runtime-gateway/shared-adapter.ts +20 -0
  51. package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +358 -266
  52. package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +136 -0
  53. package/adapters/mcp/runtime-gateway/work-adapter.ts +261 -3122
  54. package/adapters/mcp/runtime-gateway/work-controller-operations.ts +257 -0
  55. package/adapters/mcp/runtime-gateway/work-detail-projection.ts +60 -0
  56. package/adapters/mcp/runtime-gateway/work-input-wire-migration.ts +246 -0
  57. package/adapters/mcp/runtime-gateway/work-learning-operations.ts +145 -0
  58. package/adapters/mcp/runtime-gateway/work-list-projection.ts +38 -0
  59. package/adapters/mcp/runtime-gateway/work-plan-operations.ts +382 -0
  60. package/adapters/mcp/runtime-gateway/work-repair-adapter.ts +308 -0
  61. package/adapters/mcp/runtime-gateway/work-requirement-operations.ts +148 -0
  62. package/adapters/mcp/runtime-gateway/work-semantic-operations.ts +263 -0
  63. package/adapters/mcp/runtime-gateway/work-workflow-operations.ts +113 -0
  64. package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +156 -0
  65. package/adapters/mcp/server.ts +67 -23
  66. package/adapters/mcp/setup.ts +1 -3
  67. package/adapters/mcp/tool-mapping/legacy-tool-service.ts +44 -170
  68. package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +4 -9
  69. package/adapters/mcp/tool-mapping/repository-tools.ts +133 -142
  70. package/adapters/mcp/toolset-names.ts +5 -0
  71. package/adapters/mcp/toolset.ts +6 -5
  72. package/adapters/mcp/transports/http-observation.ts +365 -0
  73. package/adapters/mcp/transports/http.ts +154 -677
  74. package/adapters/mcp/transports/oauth-http.ts +322 -0
  75. package/adapters/mcp/transports/session-registry.ts +6 -0
  76. package/adapters/mcp/tunnels/openai-secure-tunnel.ts +89 -5
  77. package/assets/plugin-registry.v1.json +6 -4
  78. package/assets/reference-configs/agentic-development-flow.md +25 -0
  79. package/assets/reference-configs/global-working-rules.md +19 -0
  80. package/assets/skill-version.json +2 -2
  81. package/docs/architecture/CURRENT.md +111 -41
  82. package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +14 -5
  83. package/docs/architecture/decisions/20260823-immediate-controller-relay.md +6 -3
  84. package/docs/architecture/decisions/20260907-assistant-learning-loop.md +2 -0
  85. package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +19 -4
  86. package/docs/architecture/decisions/20260916-workflow-supervisor-authority.md +249 -0
  87. package/docs/architecture/decisions/20260917-cognitive-memory-foundation.md +82 -0
  88. package/docs/architecture/decisions/20260918-stable-candidate-release-lifecycle.md +221 -0
  89. package/docs/architecture/decisions/20260919-autonomous-work-liveness.md +62 -0
  90. package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +72 -0
  91. package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +237 -0
  92. package/docs/architecture/decisions/20261005-forge-v3-desktop-client-boundary.md +77 -0
  93. package/docs/architecture/domains/verification.md +1 -0
  94. package/docs/architecture/domains/workflow-engine.md +6 -0
  95. package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +1 -1
  96. package/docs/forge-plugin-management.md +2 -2
  97. package/docs/operations/controller-performance-and-502.md +17 -0
  98. package/docs/operations/controller-reliability-runbook.md +2 -2
  99. package/docs/operations/features.md +1 -1
  100. package/docs/operations/features.zh-CN.md +1 -1
  101. package/docs/operations/homebrew.md +2 -2
  102. package/docs/operations/mcp-tool-exposure.md +2 -0
  103. package/docs/operations/releasing.md +2 -0
  104. package/docs/operations/standalone-disaster-recovery.md +14 -6
  105. package/docs/wiki/Implementation.md +1 -1
  106. package/package.json +25 -14
  107. package/packages/kernel/cognition/api/index.ts +6 -0
  108. package/packages/kernel/cognition/application/activation-service.ts +451 -0
  109. package/packages/kernel/cognition/application/consolidation-service.ts +185 -0
  110. package/packages/kernel/cognition/application/legacy-experience-adapter.ts +38 -0
  111. package/packages/kernel/cognition/application/memory-service.ts +64 -0
  112. package/packages/kernel/cognition/domain/learning.ts +106 -0
  113. package/packages/kernel/cognition/domain/memory.ts +254 -0
  114. package/packages/kernel/controller/api/index.ts +1 -0
  115. package/packages/kernel/controller/application/continuation-service.ts +281 -0
  116. package/packages/kernel/controller/application/controller-round-service.ts +12 -0
  117. package/packages/kernel/controller/domain/controller-round-transition-policy.ts +242 -21
  118. package/packages/kernel/controller/domain/controller-round.ts +4 -1
  119. package/packages/kernel/controller/domain/execution-quality.ts +3 -1
  120. package/packages/kernel/controller/infrastructure/controller-round-store.ts +689 -103
  121. package/packages/kernel/controller/infrastructure/controller-session-store.ts +297 -71
  122. package/packages/kernel/controller/ports/controller-host.ts +2 -0
  123. package/packages/kernel/identity/api/index.ts +10 -0
  124. package/packages/kernel/identity/domain/activity-projection.ts +43 -0
  125. package/packages/kernel/identity/domain/capability-broker.ts +60 -0
  126. package/packages/kernel/identity/domain/grant.ts +72 -0
  127. package/packages/kernel/identity/domain/owned-resource.ts +116 -0
  128. package/packages/kernel/identity/domain/user-request.ts +93 -0
  129. package/packages/kernel/identity/infrastructure/activity-projection-store.ts +77 -0
  130. package/packages/kernel/identity/infrastructure/capability-broker.ts +81 -0
  131. package/packages/kernel/identity/infrastructure/grant-store.ts +284 -0
  132. package/packages/kernel/identity/infrastructure/owned-resource-store.ts +259 -0
  133. package/packages/kernel/identity/infrastructure/user-request-store.ts +182 -0
  134. package/packages/kernel/scheduler/api/index.ts +0 -2
  135. package/packages/kernel/scheduler/application/schedule-service.ts +3 -0
  136. package/packages/kernel/scheduler/application/settlement.ts +0 -15
  137. package/packages/kernel/scheduler/domain/schedule.ts +87 -0
  138. package/packages/kernel/scheduler/infrastructure/schedule-store.ts +153 -133
  139. package/packages/kernel/work/api/index.ts +3 -2
  140. package/packages/kernel/work/application/work-service.ts +17 -42
  141. package/packages/kernel/work/domain/current-task-lineage.ts +104 -0
  142. package/packages/kernel/work/domain/engineering-design.ts +10 -5
  143. package/packages/kernel/work/domain/engineering-profile.ts +8 -12
  144. package/packages/kernel/work/domain/evaluation-promotion-receipt.ts +186 -0
  145. package/packages/kernel/work/domain/execution-concurrency.ts +19 -26
  146. package/packages/kernel/work/domain/execution-snapshot.ts +0 -31
  147. package/packages/kernel/work/domain/implementation-review.ts +14 -331
  148. package/packages/kernel/work/domain/objective-graph.ts +119 -0
  149. package/packages/kernel/work/domain/project-engineering-contract.ts +23 -1
  150. package/packages/kernel/work/domain/repository-completion-receipt.ts +1 -1
  151. package/packages/kernel/work/domain/state-machine.ts +25 -63
  152. package/packages/kernel/work/domain/types.ts +57 -51
  153. package/packages/kernel/work/infrastructure/work-contract-store.ts +819 -728
  154. package/packages/kernel/work/ports/work-contract-store.ts +5 -2
  155. package/packages/plugin-runtime/browser/session-authority.ts +2 -1
  156. package/packages/plugin-runtime/computer/chatgpt-identity.ts +24 -0
  157. package/packages/plugin-runtime/computer/conversation-target.ts +143 -0
  158. package/packages/plugin-runtime/computer/index.ts +2 -0
  159. package/packages/plugin-runtime/computer/target-authority.ts +26 -1
  160. package/packages/plugin-runtime/external/unix-jsonl-transport.ts +142 -18
  161. package/packages/protocols/computer/contract.ts +27 -1
  162. package/scripts/activate-source-baseline.ts +7 -9
  163. package/scripts/canary-controller-semantic-wait.ts +12 -24
  164. package/scripts/check-mcp-compatibility.ts +48 -136
  165. package/scripts/check-runtime-architecture.mjs +622 -217
  166. package/scripts/forge-local-recovery-helper.mjs +93 -15
  167. package/scripts/lib/project-init-lib.sh +3 -0
  168. package/scripts/open-source-audit-allowlist.txt +1 -2
  169. package/scripts/run-bounded-command.mjs +5 -0
  170. package/scripts/run-governed-gate.ts +0 -1
  171. package/scripts/run-mobile-monitor-bridge.ts +0 -1
  172. package/scripts/smoke-control-plane-failure-domain.ts +94 -0
  173. package/scripts/smoke-mcp-http-runtime.ts +5 -0
  174. package/scripts/smoke-runtime-recovery.ts +12 -43
  175. package/scripts/smoke-schedule-engine.ts +23 -15
  176. package/scripts/smoke-unattended-transport-recovery.ts +223 -0
  177. package/scripts/smoke-user-request-continuation-restart.ts +232 -0
  178. package/scripts/smoke-workflow-supervisor-chrome-adapter.ts +92 -0
  179. package/scripts/smoke-workflow-supervisor-process-restart.ts +276 -0
  180. package/scripts/smoke-workflow-supervisor-restart-recovery.ts +150 -0
  181. package/scripts/smoke-workflow-supervisor.ts +103 -0
  182. package/scripts/verify-forge-runtime.sh +2 -1
  183. package/src/cli/agent-jobs/executor-health.ts +11 -34
  184. package/src/cli/agent-jobs/integration.ts +18 -49
  185. package/src/cli/agent-jobs/job-manager.ts +7 -3
  186. package/src/cli/commands/brain-assistant.ts +27 -13
  187. package/src/cli/commands/brain.ts +13 -15
  188. package/src/cli/commands/chatgpt.ts +1 -163
  189. package/src/cli/commands/recovery.ts +135 -121
  190. package/src/cli/commands/runtime.ts +3 -3
  191. package/src/cli/commands/setup-profile.ts +8 -0
  192. package/src/cli/controller/check-runner.ts +13 -2
  193. package/src/cli/controller/completion-backlog.ts +3 -3
  194. package/src/cli/controller/completion-orchestrator.ts +4 -43
  195. package/src/cli/controller/completion-target.ts +3 -72
  196. package/src/cli/controller/context/source-materializer.ts +81 -100
  197. package/src/cli/controller/context-pack.ts +10 -8
  198. package/src/cli/controller/execution-completion.ts +4 -7
  199. package/src/cli/controller/execution-policy.ts +36 -153
  200. package/src/cli/controller/governance.ts +2 -3
  201. package/src/cli/controller/issue-store.ts +4 -99
  202. package/src/cli/controller/launch-agents.ts +59 -18
  203. package/src/cli/controller/operational-plan.ts +24 -51
  204. package/src/cli/controller/runtime-config.ts +5 -1
  205. package/src/cli/controller/stuck-state-migration.ts +2 -3
  206. package/src/cli/controller/systemd-user.ts +39 -1
  207. package/src/cli/editing/edit-session.ts +1 -7
  208. package/src/cli/local-bridge/console-automations.ts +18 -13
  209. package/src/cli/local-bridge/console-view-models.ts +3 -12
  210. package/src/cli/local-bridge/facade-api.ts +64 -191
  211. package/src/cli/local-bridge/server.ts +24 -147
  212. package/src/cli/local-bridge/types.ts +0 -1
  213. package/src/cli/mcp/oauth-client-retirement.ts +74 -0
  214. package/src/cli/repositories/command-executor.ts +29 -23
  215. package/src/cli/repositories/command-scope.ts +35 -16
  216. package/src/cli/repositories/controller-home.ts +48 -0
  217. package/src/cli/repositories/ephemeral-workspace.ts +20 -30
  218. package/src/cli/repositories/git-command-executor.ts +2 -2
  219. package/src/cli/repositories/registry.ts +77 -11
  220. package/src/cli/repositories/structured-git.ts +62 -2
  221. package/src/cli/repository/session-cache.ts +92 -6
  222. package/src/runtime/context/assistant-context.ts +20 -7
  223. package/src/runtime/context/assistant-work-context.ts +89 -27
  224. package/src/runtime/context/automatic-learning.ts +565 -0
  225. package/src/runtime/context/cognitive-attention.ts +173 -0
  226. package/src/runtime/context/cognitive-skill-canary.ts +158 -0
  227. package/src/runtime/context/context-closure.ts +46 -9
  228. package/src/runtime/context/context-pack-process.ts +103 -0
  229. package/src/runtime/context/context-plane.ts +1 -9
  230. package/src/runtime/context/direct-controller-learning.ts +298 -0
  231. package/src/runtime/context/semantic-navigation-contract.ts +9 -0
  232. package/src/runtime/context/semantic-navigation.ts +6 -34
  233. package/src/runtime/context/typescript-navigation-process.ts +145 -0
  234. package/src/runtime/context/typescript-navigation.ts +89 -3
  235. package/src/runtime/control-plane/cleanup-artifact-retention.ts +212 -9
  236. package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +9 -47
  237. package/src/runtime/control-plane/execution/controller-authority-recovery.ts +34 -4
  238. package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +29 -20
  239. package/src/runtime/control-plane/execution/execution-identity.ts +23 -3
  240. package/src/runtime/control-plane/execution/repository-work-attribution.ts +7 -30
  241. package/src/runtime/control-plane/execution/retained-work-resume.ts +206 -199
  242. package/src/runtime/control-plane/execution/session-store.ts +31 -1
  243. package/src/runtime/control-plane/execution/validation.ts +6 -8
  244. package/src/runtime/control-plane/execution/work-authority-reconciler.ts +13 -42
  245. package/src/runtime/control-plane/execution/work-check-evidence.ts +137 -0
  246. package/src/runtime/control-plane/execution/work-completion-authority.ts +30 -85
  247. package/src/runtime/control-plane/execution/work-delivery-service.ts +497 -0
  248. package/src/runtime/control-plane/execution/work-evidence-policy.ts +12 -50
  249. package/src/runtime/control-plane/execution/work-execution-support.ts +50 -149
  250. package/src/runtime/control-plane/execution/work-handle-authority.ts +188 -109
  251. package/src/runtime/control-plane/execution/work-handle-store.ts +19 -43
  252. package/src/runtime/control-plane/execution/work-head-settlement.ts +53 -20
  253. package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +52 -29
  254. package/src/runtime/control-plane/execution/work-operation-service.ts +43 -27
  255. package/src/runtime/control-plane/execution/work-preparation-service.ts +126 -266
  256. package/src/runtime/control-plane/execution/work-remote-delivery.ts +2 -3
  257. package/src/runtime/control-plane/execution/work-revision-diff.ts +39 -0
  258. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +173 -186
  259. package/src/runtime/control-plane/execution/work-validation-reconciler.ts +28 -84
  260. package/src/runtime/control-plane/execution/work-verification-service.ts +406 -50
  261. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +5 -1
  262. package/src/runtime/control-plane/facade/capability-registry.ts +362 -37
  263. package/src/runtime/control-plane/facade/check-normalization.ts +3 -9
  264. package/src/runtime/control-plane/facade/codex-delegation.ts +10 -11
  265. package/src/runtime/control-plane/facade/controller-connection.ts +135 -0
  266. package/src/runtime/control-plane/facade/goal-workloop-access.ts +1 -20
  267. package/src/runtime/control-plane/facade/goal-workloop.ts +281 -1753
  268. package/src/runtime/control-plane/facade/handoff-inbox-application.ts +12 -25
  269. package/src/runtime/control-plane/facade/handoff-inbox-store.ts +256 -52
  270. package/src/runtime/control-plane/facade/index.ts +0 -1
  271. package/src/runtime/control-plane/facade/operation-digest.ts +12 -15
  272. package/src/runtime/control-plane/facade/plan-contract-store.ts +451 -991
  273. package/src/runtime/control-plane/facade/policy-gate.ts +0 -23
  274. package/src/runtime/control-plane/facade/repository-work-admission.ts +12 -22
  275. package/src/runtime/control-plane/facade/requirement-authority.ts +102 -199
  276. package/src/runtime/control-plane/facade/requirement-board.ts +3 -3
  277. package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +51 -14
  278. package/src/runtime/control-plane/facade/self-healing-loop.ts +18 -53
  279. package/src/runtime/control-plane/facade/suggested-actions.ts +15 -18
  280. package/src/runtime/control-plane/facade/types.ts +49 -108
  281. package/src/runtime/control-plane/facade/work-continuation.ts +8 -8
  282. package/src/runtime/control-plane/generated-cache-retention.ts +97 -1
  283. package/src/runtime/control-plane/global-scheduler/autonomous-continuation.ts +248 -0
  284. package/src/runtime/control-plane/global-scheduler/durable-admission.ts +1 -1
  285. package/src/runtime/control-plane/global-scheduler/maintenance.ts +239 -112
  286. package/src/runtime/control-plane/global-scheduler/reconciliation.ts +2 -1
  287. package/src/runtime/control-plane/global-scheduler/scheduler.ts +66 -40
  288. package/src/runtime/control-plane/global-scheduler/wake-signal.ts +42 -2
  289. package/src/runtime/control-plane/governance/access-policy.ts +19 -2
  290. package/src/runtime/control-plane/governance/authorization.ts +20 -3
  291. package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +63 -300
  292. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +28 -300
  293. package/src/runtime/control-plane/launcher/local-conversation-controller.ts +238 -0
  294. package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +5 -2
  295. package/src/runtime/control-plane/launcher/thin-launcher.ts +96 -240
  296. package/src/runtime/control-plane/persistence/cognition-store.ts +820 -0
  297. package/src/runtime/control-plane/persistence/experience-store.ts +162 -29
  298. package/src/runtime/control-plane/persistence/requirement-store.ts +216 -74
  299. package/src/runtime/control-plane/persistence/sqlite-store.ts +113 -6
  300. package/src/runtime/control-plane/release-retention.ts +135 -47
  301. package/src/runtime/control-plane/repository-namespace-retention.ts +2 -2
  302. package/src/runtime/control-plane/runtime-cleanup.ts +290 -21
  303. package/src/runtime/control-plane/workspace/project-onboarding.ts +80 -0
  304. package/src/runtime/control-plane/workspace/semantic-sync-service.ts +19 -5
  305. package/src/runtime/control-plane/workspace/workspace-store.ts +169 -0
  306. package/src/runtime/diagnostics/incident-repair.ts +313 -146
  307. package/src/runtime/diagnostics/mcp-timing.ts +114 -0
  308. package/src/runtime/evidence/artifact-store.ts +158 -40
  309. package/src/runtime/evidence/evidence-store.ts +112 -8
  310. package/src/runtime/evidence/output-handle-index.ts +225 -0
  311. package/src/runtime/evidence/result-store.ts +158 -44
  312. package/src/runtime/execution/jobs/store.ts +3 -4
  313. package/src/runtime/execution/managed-workspace.ts +57 -0
  314. package/src/runtime/execution/process-runtime/check-facade.ts +1 -1
  315. package/src/runtime/execution/process-runtime/check-result-retention.ts +2 -2
  316. package/src/runtime/execution/process-runtime/check-result.ts +105 -1
  317. package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +18 -8
  318. package/src/runtime/execution/process-runtime/command-facade.ts +79 -27
  319. package/src/runtime/execution/process-runtime/gc.ts +15 -2
  320. package/src/runtime/execution/process-runtime/handle-index.ts +176 -0
  321. package/src/runtime/execution/process-runtime/host-command-lane.ts +139 -0
  322. package/src/runtime/execution/process-runtime/index.ts +3 -0
  323. package/src/runtime/execution/process-runtime/lightweight-managed.ts +251 -72
  324. package/src/runtime/execution/process-runtime/persisted-check.ts +3 -3
  325. package/src/runtime/execution/process-runtime/process-runner-entry.ts +47 -5
  326. package/src/runtime/execution/process-runtime/process-scope.ts +160 -0
  327. package/src/runtime/execution/process-runtime/resource-claims.ts +65 -61
  328. package/src/runtime/execution/process-runtime/runtime.ts +35 -2
  329. package/src/runtime/execution/process-runtime/store.ts +30 -2
  330. package/src/runtime/execution/process-runtime/types.ts +6 -1
  331. package/src/runtime/execution/workers/executor.ts +2 -6
  332. package/src/runtime/platform/service-inventory.ts +130 -0
  333. package/src/runtime/platform/service-manager.ts +8 -0
  334. package/src/runtime/plugins/action-application.ts +85 -28
  335. package/src/runtime/plugins/app-store-connect-adapter.ts +38 -14
  336. package/src/runtime/plugins/browser-adapter.ts +757 -34
  337. package/src/runtime/plugins/browser-automation-service.ts +23 -3
  338. package/src/runtime/plugins/browser-macos-bridge.ts +321 -29
  339. package/src/runtime/plugins/browser-manifest-surface.ts +45 -11
  340. package/src/runtime/plugins/browser-native-session-service.ts +63 -13
  341. package/src/runtime/plugins/browser-registration.ts +16 -0
  342. package/src/runtime/plugins/browser-runtime.ts +14 -1
  343. package/src/runtime/plugins/browser-session-authority.ts +2 -2
  344. package/src/runtime/plugins/browser-session-store.ts +46 -76
  345. package/src/runtime/plugins/capability-authorization-grants.ts +258 -62
  346. package/src/runtime/plugins/computer-chatgpt-browser-adapter-installer.ts +219 -0
  347. package/src/runtime/plugins/computer-chatgpt-macos-target.ts +891 -0
  348. package/src/runtime/plugins/computer-registration.ts +222 -11
  349. package/src/runtime/plugins/desktop-operator-external-policy.ts +36 -4
  350. package/src/runtime/plugins/desktop-operator-registration.ts +12 -4
  351. package/src/runtime/plugins/external-adapter.ts +42 -6
  352. package/src/runtime/plugins/external-registration.ts +21 -1
  353. package/src/runtime/plugins/gmail-adapter.ts +23 -2
  354. package/src/runtime/plugins/google-calendar-adapter.ts +2 -2
  355. package/src/runtime/plugins/google-shared.ts +14 -7
  356. package/src/runtime/plugins/google-tasks-adapter.ts +2 -2
  357. package/src/runtime/plugins/ios-adapter.ts +1 -1
  358. package/src/runtime/plugins/lightweight-action.ts +208 -2
  359. package/src/runtime/plugins/local-system-adapter.ts +12 -2
  360. package/src/runtime/plugins/managed-process-adapter.ts +12 -5
  361. package/src/runtime/plugins/plugin-action-sidecar.ts +17 -13
  362. package/src/runtime/plugins/plugin-management-adapter.ts +1 -1
  363. package/src/runtime/plugins/store.ts +602 -428
  364. package/src/runtime/plugins/types.ts +20 -0
  365. package/src/runtime/plugins/xiaohongshu-publish.ts +16 -0
  366. package/src/runtime/projections/invalidation.ts +7 -3
  367. package/src/runtime/projections/materialized-view.ts +80 -36
  368. package/src/runtime/recovery/actions.ts +3 -3
  369. package/src/runtime/recovery/capability-action-application.ts +46 -45
  370. package/src/runtime/recovery/lifecycle-inventory.ts +29 -29
  371. package/src/runtime/recovery/maintenance-executor.ts +374 -123
  372. package/src/runtime/recovery/store.ts +29 -11
  373. package/src/runtime/release/release-coordinator.ts +296 -0
  374. package/src/runtime/release/release-session.ts +716 -0
  375. package/src/runtime/release/release-state-migration.ts +25 -0
  376. package/src/runtime/resources/leases/store.ts +56 -25
  377. package/src/runtime/root/computer-composition.ts +191 -6
  378. package/src/runtime/root/controller-progression-composition.ts +192 -0
  379. package/src/runtime/root/controller-round-composition.ts +20 -1
  380. package/src/runtime/root/deployment-topology.ts +106 -0
  381. package/src/runtime/root/entry.ts +4 -3
  382. package/src/runtime/root/known-good-recovery.ts +184 -0
  383. package/src/runtime/root/local-bridge.ts +0 -1
  384. package/src/runtime/root/mcp-transport.ts +111 -18
  385. package/src/runtime/root/ownership.ts +261 -9
  386. package/src/runtime/root/package-connector-service.ts +105 -19
  387. package/src/runtime/root/package-runtime-release.ts +117 -18
  388. package/src/runtime/root/package-runtime-service.ts +17 -11
  389. package/src/runtime/root/release-execution-canary.ts +44 -12
  390. package/src/runtime/root/release-loader.ts +90 -8
  391. package/src/runtime/root/release-manifest.ts +80 -6
  392. package/src/runtime/root/release-materialize.ts +372 -28
  393. package/src/runtime/root/release-store.ts +395 -36
  394. package/src/runtime/root/runtime-lane.ts +191 -0
  395. package/src/runtime/root/runtime.ts +159 -27
  396. package/src/runtime/root/scheduled-controller-composition.ts +28 -3
  397. package/src/runtime/root/service-runner.ts +2 -2
  398. package/src/runtime/root/service.ts +36 -33
  399. package/src/runtime/root/status.ts +48 -0
  400. package/src/runtime/root/types.ts +32 -3
  401. package/src/runtime/root/workflow-supervisor-composition.ts +493 -0
  402. package/src/runtime/root/workflow-supervisor-runtime.ts +209 -0
  403. package/src/runtime/root/write-fence.ts +50 -2
  404. package/src/runtime/safe-tooling/google-credential-store.ts +76 -21
  405. package/src/runtime/safe-tooling/google-oauth-broker.ts +25 -7
  406. package/src/runtime/safe-tooling/workspace-auth.ts +1 -1
  407. package/src/runtime/shared/bounded-child-supervisor.ts +9 -1
  408. package/src/runtime/shared/process-environment.ts +20 -9
  409. package/src/runtime/shared/response-budget.ts +1 -3
  410. package/src/runtime/standalone-recovery/controller-home-migration.ts +16 -24
  411. package/src/runtime/standalone-recovery/core.ts +3702 -342
  412. package/src/runtime/standalone-recovery/entry.ts +469 -39
  413. package/src/runtime/standalone-recovery/installer.ts +262 -148
  414. package/src/runtime/standalone-recovery/mcp-server.ts +29 -193
  415. package/src/runtime/standalone-recovery/operation-lock.ts +1 -1
  416. package/src/runtime/standalone-recovery/performance.ts +54 -16
  417. package/src/runtime/standalone-recovery/release.ts +53 -5
  418. package/src/runtime/standalone-recovery/service-labels.ts +5 -2
  419. package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +5 -2
  420. package/src/runtime/workflow/schedules/browser-probe.ts +17 -6
  421. package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +10 -3
  422. package/src/runtime/workflow/schedules/engine.ts +138 -172
  423. package/src/runtime/workflow/schedules/work-continuation.ts +44 -5
  424. package/src/runtime/workflows/runtime.ts +15 -19
  425. package/src/testing/test-governance.ts +5 -1
  426. package/supervisor/chatgpt-conversation.ts +23 -0
  427. package/supervisor/client.ts +201 -0
  428. package/supervisor/control-plane.ts +868 -0
  429. package/supervisor/entry.ts +15 -0
  430. package/supervisor/forge-validators.ts +80 -0
  431. package/supervisor/index.ts +5 -0
  432. package/supervisor/native-browser-adapter.ts +786 -0
  433. package/supervisor/native-messaging/host.ts +39 -0
  434. package/supervisor/native-messaging/manifest.ts +26 -0
  435. package/supervisor/native-messaging/protocol.ts +27 -0
  436. package/supervisor/paths.ts +18 -0
  437. package/supervisor/protocol.ts +202 -0
  438. package/supervisor/server.ts +404 -0
  439. package/supervisor/store.ts +1451 -0
  440. package/supervisor/tsconfig.json +8 -0
  441. package/supervisor/types.ts +255 -0
  442. package/adapters/chatgpt/controller-host.ts +0 -119
  443. package/adapters/mcp/controller-round-compatibility.ts +0 -184
  444. package/adapters/mcp/frozen-client-semantic-compatibility.ts +0 -292
  445. package/adapters/mcp/runtime-gateway/work-compat-adapter.ts +0 -502
  446. package/packages/kernel/progression/api/index.ts +0 -2
  447. package/packages/kernel/progression/application/projector.ts +0 -211
  448. package/packages/kernel/progression/domain/types.ts +0 -116
  449. package/packages/kernel/progression/index.ts +0 -1
  450. package/packages/kernel/scheduler/application/continuation-service.ts +0 -212
  451. package/packages/kernel/scheduler/domain/continuation.ts +0 -38
  452. package/packages/kernel/scheduler/infrastructure/continuation-dispatch-store.ts +0 -38
  453. package/packages/kernel/work/domain/admission-policy.ts +0 -34
  454. package/scripts/benchmark-background-check-overlap.ts +0 -228
  455. package/scripts/benchmark-computer-hotpath.ts +0 -255
  456. package/scripts/benchmark-controller-hotpath.ts +0 -212
  457. package/scripts/benchmark-controller-round2.ts +0 -191
  458. package/scripts/benchmark-ios-agent-device.ts +0 -511
  459. package/scripts/benchmark-mcp-host.sh +0 -117
  460. package/scripts/benchmark-mcp-transport.ts +0 -169
  461. package/scripts/benchmark-operational-memory-activation.ts +0 -235
  462. package/scripts/benchmark-operational-shadow.ts +0 -28
  463. package/scripts/benchmark-quality-harness.ts +0 -146
  464. package/scripts/benchmark-route-session-concurrency.ts +0 -915
  465. package/scripts/benchmark-thin-harness-gateway-ab.ts +0 -632
  466. package/scripts/benchmark-thin-harness-mcp-e2e.ts +0 -498
  467. package/scripts/benchmark-thin-harness.ts +0 -251
  468. package/scripts/benchmark-typescript-navigation.ts +0 -186
  469. package/scripts/benchmark-work-efficiency.ts +0 -334
  470. package/scripts/build-controller-ui.ts +0 -28
  471. package/scripts/check-npm-release.sh +0 -32
  472. package/scripts/check-public-release-surface.sh +0 -19
  473. package/scripts/check-release-published.sh +0 -57
  474. package/scripts/check-release-readiness.sh +0 -37
  475. package/scripts/check-release-version.mjs +0 -74
  476. package/scripts/check-tarball-install-smoke.sh +0 -150
  477. package/scripts/package-source-archive.sh +0 -147
  478. package/scripts/public-release-files.txt +0 -39
  479. package/scripts/public-release.ts +0 -174
  480. package/scripts/publish-release-tarball.sh +0 -27
  481. package/scripts/route-nl-vs-ts-eval.ts +0 -679
  482. package/scripts/stage-runtime-release.ts +0 -44
  483. package/src/cli/controller/progress.ts +0 -656
  484. package/src/cli/controller/work-mode.ts +0 -181
  485. package/src/cli/local-bridge/console-assets.ts +0 -17
  486. package/src/cli/local-bridge/dashboard.ts +0 -17
  487. package/src/cli/local-bridge/frontend/src/App.tsx +0 -10
  488. package/src/cli/local-bridge/frontend/src/components/Button.tsx +0 -1
  489. package/src/cli/local-bridge/frontend/src/components/DetailPane.tsx +0 -3
  490. package/src/cli/local-bridge/frontend/src/components/SearchField.tsx +0 -1
  491. package/src/cli/local-bridge/frontend/src/components/SectionHeader.tsx +0 -1
  492. package/src/cli/local-bridge/frontend/src/components/Segmented.tsx +0 -1
  493. package/src/cli/local-bridge/frontend/src/components/StatusText.tsx +0 -3
  494. package/src/cli/local-bridge/frontend/src/design/icons.tsx +0 -11
  495. package/src/cli/local-bridge/frontend/src/design/tokens.css +0 -8
  496. package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +0 -153
  497. package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +0 -37
  498. package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +0 -183
  499. package/src/cli/local-bridge/frontend/src/features/repositories/RepositoriesView.tsx +0 -2
  500. package/src/cli/local-bridge/frontend/src/features/system/SystemView.tsx +0 -2
  501. package/src/cli/local-bridge/frontend/src/features/work/WorkView.tsx +0 -4
  502. package/src/cli/local-bridge/frontend/src/lib/api.ts +0 -30
  503. package/src/cli/local-bridge/frontend/src/lib/format.ts +0 -4
  504. package/src/cli/local-bridge/frontend/src/lib/routes.ts +0 -7
  505. package/src/cli/local-bridge/frontend/src/main.tsx +0 -1
  506. package/src/cli/local-bridge/frontend/src/shell/AppShell.tsx +0 -1
  507. package/src/cli/local-bridge/frontend/src/shell/CommandBar.tsx +0 -2
  508. package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +0 -4
  509. package/src/cli/local-bridge/frontend/src/styles.css +0 -28
  510. package/src/cli/local-bridge/frontend/src/types.ts +0 -15
  511. package/src/cli/local-bridge/frontend/src/vite-env.d.ts +0 -1
  512. package/src/cli/local-bridge/frontend/vite.config.ts +0 -27
  513. package/src/cli/local-bridge/ui-dist/app.css +0 -1
  514. package/src/cli/local-bridge/ui-dist/app.js +0 -11228
  515. package/src/runtime/control-plane/execution/content-equivalent-commit-authority.ts +0 -169
  516. package/src/runtime/control-plane/execution/direct-canonical-work-reconciliation.ts +0 -85
  517. package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +0 -655
  518. package/src/runtime/control-plane/execution/work-finalization-service.ts +0 -2850
  519. package/src/runtime/control-plane/execution/work-path-scope.ts +0 -37
  520. package/src/runtime/control-plane/execution/work-task-receipt.ts +0 -468
  521. package/src/runtime/control-plane/facade/controller-round-relay.ts +0 -3
  522. package/src/runtime/control-plane/facade/work-admission-policy.ts +0 -142
  523. package/src/runtime/control-plane/facade/work-implementation-review.ts +0 -2
  524. package/src/runtime/control-plane/facade/work-state-machine.ts +0 -2
  525. package/src/runtime/control-plane/facade/work-task-projection.ts +0 -66
  526. package/src/runtime/control-plane/routing/index.ts +0 -1
  527. package/src/runtime/control-plane/routing/route-policy.ts +0 -401
  528. package/src/runtime/control-plane/routing/workspace-admission.ts +0 -70
@@ -1,6 +1,6 @@
1
1
  import { getControllerSession, releaseObservedControllerSession } from '../../../../packages/kernel/controller/api/index';
2
- import { getWorkContract, isTerminalWorkContractStatus } from '../../../../packages/kernel/work/api/index';
3
- import { listSchedules } from '../../../../packages/kernel/scheduler/api/index';
2
+ import { listUserRequests } from '../../../../packages/kernel/identity/api/index';
3
+ import { getWorkContract, semanticWorkState } from '../../../../packages/kernel/work/api/index';
4
4
  import type { HandoffItem } from './types';
5
5
  import {
6
6
  acknowledgeHandoffItem,
@@ -44,8 +44,8 @@ export type HandoffInboxApplicationRunner = (
44
44
  ) => ReturnType<typeof runHandoffInboxApplication>;
45
45
 
46
46
  export interface HandoffAttentionResolver {
47
- workIsTerminal(workId: string): boolean | undefined;
48
- scheduleIsEnabled(scheduleId: string): boolean | undefined;
47
+ userRequestIsPending(requestId: string): boolean | undefined;
48
+ owningWorkIsOpen?(workId: string): boolean | undefined;
49
49
  }
50
50
 
51
51
  /**
@@ -55,15 +55,11 @@ export interface HandoffAttentionResolver {
55
55
  */
56
56
  export function handoffRequiresAttention(item: HandoffItem, resolver: HandoffAttentionResolver): boolean {
57
57
  if (item.status !== 'pending') return false;
58
+ const requestId = item.canonicalUserRequestId?.trim();
59
+ if (!requestId) return false;
58
60
  const workId = item.workId?.trim();
59
- if (workId && resolver.workIsTerminal(workId) === true) return false;
60
-
61
- const scheduleId = item.currentState.taskId?.trim();
62
- const scheduleFailure = item.creationReason === 'repeated_infrastructure_failure'
63
- && Boolean(scheduleId)
64
- && (item.id.startsWith('schedule-failure-') || item.id.startsWith('schedule-'));
65
- if (scheduleFailure && scheduleId && resolver.scheduleIsEnabled(scheduleId) === false) return false;
66
- return true;
61
+ if (workId && resolver.owningWorkIsOpen?.(workId) === false) return false;
62
+ return resolver.userRequestIsPending(requestId) === true;
67
63
  }
68
64
 
69
65
  export function listHandoffAttentionItems(
@@ -71,22 +67,13 @@ export function listHandoffAttentionItems(
71
67
  limit = 50,
72
68
  ): HandoffItem[] {
73
69
  const candidates = listHandoffItems({ ...store, status: 'pending', limit: 100 });
74
- const scheduleIds = new Set(candidates
75
- .filter((item) => item.creationReason === 'repeated_infrastructure_failure'
76
- && (item.id.startsWith('schedule-failure-') || item.id.startsWith('schedule-')))
77
- .map((item) => item.currentState.taskId?.trim())
78
- .filter((value): value is string => Boolean(value)));
79
- const schedules = scheduleIds.size > 0
80
- ? new Map(listSchedules(store.controllerHome, store.repoId).map((schedule) => [schedule.scheduleId, schedule.enabled] as const))
81
- : new Map<string, boolean>();
70
+ const pendingRequests = new Set(listUserRequests(store.controllerHome, 'pending').map((request) => request.requestId));
82
71
  const resolver: HandoffAttentionResolver = {
83
- workIsTerminal: (workId) => {
72
+ userRequestIsPending: (requestId) => pendingRequests.has(requestId),
73
+ owningWorkIsOpen: (workId) => {
84
74
  const work = getWorkContract(store, workId);
85
- return work ? isTerminalWorkContractStatus(work.status) : undefined;
75
+ return work ? semanticWorkState(work) === 'open' : undefined;
86
76
  },
87
- scheduleIsEnabled: (scheduleId) => scheduleIds.has(scheduleId)
88
- ? schedules.get(scheduleId) ?? false
89
- : undefined,
90
77
  };
91
78
  const boundedLimit = Math.max(1, Math.min(Math.trunc(limit), 100));
92
79
  return candidates.filter((item) => handoffRequiresAttention(item, resolver)).slice(0, boundedLimit);
@@ -1,5 +1,12 @@
1
- import { mkdirSync } from 'fs';
2
- import { join } from 'path';
1
+ import {
2
+ listUserRequests,
3
+ recordUserRequest,
4
+ resolveUserRequest,
5
+ type CreateUserRequestInput,
6
+ type UserRequest,
7
+ } from '../../../../packages/kernel/identity/api/index';
8
+ import { existsSync, mkdirSync, renameSync } from 'fs';
9
+ import { dirname, join } from 'path';
3
10
  import { repositoryControllerRoot } from '../../../cli/repositories/controller-home';
4
11
  import { withControllerLock } from '../../../cli/repositories/locks';
5
12
  import { readJsonFile, sanitizeFileComponent, writeJsonAtomic } from '../../shared/json-files';
@@ -51,21 +58,35 @@ export interface HandoffItemSummary {
51
58
  blockingDecision?: string;
52
59
  }
53
60
 
54
- /** Only create handoffs for judgement points — never ordinary logs/events. */
61
+ /** Genuine person-only blockers. Mechanical failures stay in their owning runtime domain. */
55
62
  export const HANDOFF_ELIGIBLE_REASONS = new Set<HandoffCreationReason>([
56
63
  'policy_approval_required',
57
64
  'ambiguous_outcome',
58
65
  'missing_authorization',
59
66
  'invalid_objective',
60
- 'repeated_infrastructure_failure',
61
- 'codex_worker_requires_review',
62
67
  'destructive_action_requires_confirmation',
63
68
  ]);
64
69
 
70
+ interface HandoffMigrationMarker {
71
+ schemaVersion: 1;
72
+ repoId: string;
73
+ migratedAt: string;
74
+ legacyItemCount: number;
75
+ migratedUserRequestCount: number;
76
+ skippedMechanicalCount: number;
77
+ archivedPath?: string;
78
+ }
79
+
65
80
  function nowIso(options: HandoffInboxStoreOptions): string {
66
81
  return options.now?.() ?? new Date().toISOString();
67
82
  }
68
83
 
84
+ function usesCanonicalUserRequestStore(
85
+ options: HandoffInboxStoreOptions,
86
+ ): options is HandoffInboxStoreOptions & { controllerHome: string; repoId: string } {
87
+ return Boolean(options.controllerHome && options.repoId && !options.root);
88
+ }
89
+
69
90
  function withHandoffInboxWriteLock<T>(
70
91
  options: HandoffInboxStoreOptions,
71
92
  owner: string,
@@ -74,7 +95,7 @@ function withHandoffInboxWriteLock<T>(
74
95
  if (!options.controllerHome || !options.repoId || options.root) return operation();
75
96
  return withControllerLock(
76
97
  options.controllerHome,
77
- { scope: 'task', repoId: options.repoId, taskId: 'handoff-inbox' },
98
+ { scope: 'task', repoId: options.repoId, taskId: 'handoff-inbox-migration' },
78
99
  owner,
79
100
  operation,
80
101
  );
@@ -97,24 +118,213 @@ export function handoffInboxPath(location: HandoffInboxStoreLocation): string {
97
118
  return join(handoffInboxRoot(location), 'index.json');
98
119
  }
99
120
 
121
+ function handoffMigrationMarkerPath(options: HandoffInboxStoreOptions & { controllerHome: string; repoId: string }): string {
122
+ return join(
123
+ options.controllerHome,
124
+ 'system',
125
+ 'user-requests',
126
+ 'migrations',
127
+ `handoff-inbox-${sanitizeFileComponent(options.repoId)}.json`,
128
+ );
129
+ }
130
+
100
131
  export function emptyHandoffInboxStore(updatedAt: string): HandoffInboxStore {
101
132
  return { schemaVersion: 1, updatedAt, items: [] };
102
133
  }
103
134
 
104
- export function readHandoffInboxStore(options: HandoffInboxStoreOptions): HandoffInboxStore {
135
+ function readLegacyHandoffInboxStore(options: HandoffInboxStoreOptions): HandoffInboxStore {
105
136
  return readJsonFile<HandoffInboxStore>(handoffInboxPath(options), emptyHandoffInboxStore(nowIso(options)));
106
137
  }
107
138
 
108
- export function writeHandoffInboxStore(options: HandoffInboxStoreOptions, store: HandoffInboxStore): HandoffInboxStore {
109
- writeJsonAtomic(handoffInboxPath(options), store);
110
- return store;
111
- }
112
-
113
139
  export function shouldCreateHandoff(reason: HandoffCreationReason | string | undefined): boolean {
114
140
  if (!reason) return false;
115
141
  return HANDOFF_ELIGIBLE_REASONS.has(reason as HandoffCreationReason);
116
142
  }
117
143
 
144
+ function userActionForHandoff(item: Pick<HandoffItem, 'creationReason'>): CreateUserRequestInput['actionRequired'] | undefined {
145
+ return item.creationReason === 'missing_authorization' || item.creationReason === 'policy_approval_required'
146
+ ? 'grant_permission'
147
+ : item.creationReason === 'destructive_action_requires_confirmation'
148
+ ? 'confirm_destructive'
149
+ : item.creationReason === 'ambiguous_outcome' || item.creationReason === 'invalid_objective'
150
+ ? 'product_decision'
151
+ : undefined;
152
+ }
153
+
154
+ function canonicalUserRequestInput(item: HandoffItem): CreateUserRequestInput | undefined {
155
+ const actionRequired = userActionForHandoff(item);
156
+ if (!actionRequired) return undefined;
157
+ const rootCauseKey = ['user-request', item.repoId, item.workId ?? 'repo', item.creationReason ?? 'decision', item.reason].join(':');
158
+ return {
159
+ requestId: item.canonicalUserRequestId?.trim() || item.id,
160
+ kind: actionRequired === 'product_decision' ? 'user_decision_request' : 'user_action_request',
161
+ rootCauseKey,
162
+ title: item.title,
163
+ summary: item.summary,
164
+ actionRequired,
165
+ targetScope: {
166
+ scopeKind: item.workId ? 'work' : 'repository',
167
+ scopeId: item.workId ?? item.repoId,
168
+ repoId: item.repoId,
169
+ ...(item.workId ? { workId: item.workId } : {}),
170
+ },
171
+ presentation: {
172
+ legacyHandoffId: item.id,
173
+ severity: item.severity,
174
+ creationReason: item.creationReason,
175
+ reason: item.reason,
176
+ currentState: item.currentState as unknown as Record<string, unknown>,
177
+ attemptedActions: item.attemptedActions,
178
+ evidenceRefs: item.evidenceRefs,
179
+ blockingDecision: item.blockingDecision,
180
+ recommendedDecision: item.recommendedDecision,
181
+ recommendedPrompt: item.recommendedPrompt,
182
+ recommendedContinuationPrompt: item.recommendedContinuationPrompt,
183
+ approvalAction: item.approvalAction,
184
+ suggestedNextActions: item.suggestedNextActions,
185
+ },
186
+ };
187
+ }
188
+
189
+ function projectedStatus(request: UserRequest): HandoffStatus {
190
+ if (request.status === 'pending') return 'pending';
191
+ const decision = request.resolution?.decision.trim().toLowerCase() ?? '';
192
+ return request.status === 'cancelled' || decision === 'dismissed' || decision.startsWith('dismissed:')
193
+ ? 'dismissed'
194
+ : 'resolved';
195
+ }
196
+
197
+ function projectedCreationReason(value: string | undefined): HandoffCreationReason | undefined {
198
+ return value && HANDOFF_ELIGIBLE_REASONS.has(value as HandoffCreationReason)
199
+ ? value as HandoffCreationReason
200
+ : undefined;
201
+ }
202
+
203
+ function projectUserRequest(request: UserRequest, fallbackRepoId: string): HandoffItem {
204
+ const presentation = request.presentation;
205
+ const repoId = request.targetScope?.repoId ?? fallbackRepoId;
206
+ const workId = request.targetScope?.workId;
207
+ const id = presentation?.legacyHandoffId?.trim() || request.requestId;
208
+ const status = projectedStatus(request);
209
+ return {
210
+ schemaVersion: 1,
211
+ id,
212
+ repoId,
213
+ ...(workId ? { workId } : {}),
214
+ canonicalUserRequestId: request.requestId,
215
+ title: request.title,
216
+ severity: presentation?.severity ?? 'needs_review',
217
+ status,
218
+ reason: presentation?.reason ?? request.summary,
219
+ creationReason: projectedCreationReason(presentation?.creationReason),
220
+ summary: request.summary,
221
+ currentState: (presentation?.currentState ?? {
222
+ repoId,
223
+ ...(workId ? { workId } : {}),
224
+ statusSummary: status === 'pending' ? 'waiting for user action or decision' : 'user request resolved',
225
+ }) as unknown as HandoffItem['currentState'],
226
+ attemptedActions: presentation?.attemptedActions ?? [],
227
+ evidenceRefs: (presentation?.evidenceRefs ?? []) as HandoffItem['evidenceRefs'],
228
+ blockingDecision: presentation?.blockingDecision,
229
+ recommendedDecision: presentation?.recommendedDecision ?? 'Complete the requested user action or decision.',
230
+ recommendedPrompt: presentation?.recommendedPrompt ?? `Resolve UserRequest ${request.requestId}.`,
231
+ recommendedContinuationPrompt: presentation?.recommendedContinuationPrompt,
232
+ approvalAction: presentation?.approvalAction as HandoffItem['approvalAction'],
233
+ suggestedNextActions: (presentation?.suggestedNextActions ?? []) as HandoffItem['suggestedNextActions'],
234
+ decision: request.resolution?.decision,
235
+ resolver: request.resolution?.resolvedBy,
236
+ createdAt: request.createdAt,
237
+ updatedAt: request.updatedAt,
238
+ };
239
+ }
240
+
241
+ function userRequestsForRepository(
242
+ options: HandoffInboxStoreOptions & { controllerHome: string; repoId: string },
243
+ ): UserRequest[] {
244
+ return listUserRequests(options.controllerHome, 'all')
245
+ .filter((request) => request.targetScope?.repoId === options.repoId);
246
+ }
247
+
248
+ function requestForHandoffId(
249
+ options: HandoffInboxStoreOptions & { controllerHome: string; repoId: string },
250
+ id: string,
251
+ ): UserRequest | undefined {
252
+ const normalized = sanitizeFileComponent(id);
253
+ return userRequestsForRepository(options).find((request) => (
254
+ request.requestId === normalized
255
+ || request.presentation?.legacyHandoffId === normalized
256
+ ));
257
+ }
258
+
259
+ /**
260
+ * One-time authority migration. Genuine human Handoffs become canonical
261
+ * UserRequests; mechanical/worker-review rows are archived as history only.
262
+ * After the marker is written, the legacy index is never read again.
263
+ */
264
+ export function migrateLegacyHandoffInbox(
265
+ options: HandoffInboxStoreOptions & { controllerHome: string; repoId: string },
266
+ ): HandoffMigrationMarker {
267
+ const markerPath = handoffMigrationMarkerPath(options);
268
+ if (existsSync(markerPath)) return readJsonFile<HandoffMigrationMarker>(markerPath);
269
+ return withHandoffInboxWriteLock(options, `migrate-handoff-inbox:${options.repoId}`, () => {
270
+ if (existsSync(markerPath)) return readJsonFile<HandoffMigrationMarker>(markerPath);
271
+ const legacyPath = handoffInboxPath(options);
272
+ const legacyStore = existsSync(legacyPath)
273
+ ? readJsonFile<HandoffInboxStore>(legacyPath, emptyHandoffInboxStore(nowIso(options)))
274
+ : emptyHandoffInboxStore(nowIso(options));
275
+ let migratedUserRequestCount = 0;
276
+ let skippedMechanicalCount = 0;
277
+ for (const item of legacyStore.items) {
278
+ const input = canonicalUserRequestInput(item);
279
+ if (!input) {
280
+ skippedMechanicalCount += 1;
281
+ continue;
282
+ }
283
+ let request = recordUserRequest(options.controllerHome, input);
284
+ if (isTerminalHandoffStatus(item.status) && request.status === 'pending') {
285
+ request = resolveUserRequest(options.controllerHome, {
286
+ requestId: request.requestId,
287
+ decision: item.decision?.trim() || item.status,
288
+ resolvedBy: item.resolver?.trim() || 'handoff-migration',
289
+ });
290
+ }
291
+ void request;
292
+ migratedUserRequestCount += 1;
293
+ }
294
+ const migratedAt = nowIso(options);
295
+ let archivedPath: string | undefined;
296
+ const marker: HandoffMigrationMarker = {
297
+ schemaVersion: 1,
298
+ repoId: options.repoId,
299
+ migratedAt,
300
+ legacyItemCount: legacyStore.items.length,
301
+ migratedUserRequestCount,
302
+ skippedMechanicalCount,
303
+ };
304
+ mkdirSync(dirname(markerPath), { recursive: true });
305
+ writeJsonAtomic(markerPath, marker);
306
+ if (existsSync(legacyPath)) {
307
+ archivedPath = `${legacyPath}.migrated-${Date.now()}`;
308
+ try {
309
+ renameSync(legacyPath, archivedPath);
310
+ } catch {
311
+ archivedPath = undefined;
312
+ }
313
+ }
314
+ const persisted = { ...marker, ...(archivedPath ? { archivedPath } : {}) };
315
+ if (archivedPath) writeJsonAtomic(markerPath, persisted);
316
+ return persisted;
317
+ });
318
+ }
319
+
320
+ export function readHandoffInboxStore(options: HandoffInboxStoreOptions): HandoffInboxStore {
321
+ if (!usesCanonicalUserRequestStore(options)) return readLegacyHandoffInboxStore(options);
322
+ migrateLegacyHandoffInbox(options);
323
+ const items = userRequestsForRepository(options).map((request) => projectUserRequest(request, options.repoId));
324
+ const updatedAt = items.reduce((latest, item) => item.updatedAt > latest ? item.updatedAt : latest, nowIso(options));
325
+ return { schemaVersion: 1, updatedAt, items };
326
+ }
327
+
118
328
  export function createHandoffItem(options: HandoffInboxStoreOptions, input: CreateHandoffInput): HandoffItem {
119
329
  if (input.creationReason && !shouldCreateHandoff(input.creationReason)) {
120
330
  throw new Error(`handoff creation reason is not eligible: ${input.creationReason}`);
@@ -132,19 +342,16 @@ export function createHandoffItem(options: HandoffInboxStoreOptions, input: Crea
132
342
  createdAt: at,
133
343
  updatedAt: input.updatedAt ?? at,
134
344
  };
135
- return withHandoffInboxWriteLock(options, `create-handoff:${item.id}`, () => {
136
- const store = readHandoffInboxStore(options);
137
- if (store.items.some((existing) => existing.id === item.id)) {
138
- throw new Error(`handoff already exists: ${item.id}`);
139
- }
140
- const nextStore: HandoffInboxStore = {
141
- schemaVersion: 1,
142
- updatedAt: item.updatedAt,
143
- items: [item, ...store.items],
144
- };
145
- writeHandoffInboxStore(options, nextStore);
146
- return item;
147
- });
345
+ if (!usesCanonicalUserRequestStore(options)) {
346
+ throw new Error('HANDOFF_LEGACY_STORE_READ_ONLY: provide controllerHome + repoId so UserRequest owns the durable write');
347
+ }
348
+ migrateLegacyHandoffInbox(options);
349
+ const requestInput = canonicalUserRequestInput(item);
350
+ if (!requestInput) {
351
+ throw new Error('HANDOFF_USER_REQUEST_REQUIRED: mechanical failures must remain in their owning runtime domain');
352
+ }
353
+ const request = recordUserRequest(options.controllerHome, requestInput);
354
+ return projectUserRequest(request, options.repoId);
148
355
  }
149
356
 
150
357
  export function listHandoffItems(options: ListHandoffOptions): HandoffItem[] {
@@ -187,8 +394,13 @@ export function summarizeHandoffItem(item: HandoffItem): HandoffItemSummary {
187
394
  }
188
395
 
189
396
  export function getHandoffItem(options: HandoffInboxStoreOptions, id: string): HandoffItem | undefined {
190
- const sanitizedId = sanitizeFileComponent(id);
191
- return readHandoffInboxStore(options).items.find((item) => item.id === sanitizedId);
397
+ if (!usesCanonicalUserRequestStore(options)) {
398
+ const sanitizedId = sanitizeFileComponent(id);
399
+ return readLegacyHandoffInboxStore(options).items.find((item) => item.id === sanitizedId);
400
+ }
401
+ migrateLegacyHandoffInbox(options);
402
+ const request = requestForHandoffId(options, id);
403
+ return request ? projectUserRequest(request, options.repoId) : undefined;
192
404
  }
193
405
 
194
406
  function setHandoffStatus(
@@ -198,22 +410,21 @@ function setHandoffStatus(
198
410
  patch: Partial<Pick<HandoffItem, 'decision' | 'resolver'>> = {},
199
411
  ): HandoffItem {
200
412
  const sanitizedId = sanitizeFileComponent(id);
201
- return withHandoffInboxWriteLock(options, `update-handoff:${sanitizedId}`, () => {
202
- const store = readHandoffInboxStore(options);
203
- const index = store.items.findIndex((item) => item.id === sanitizedId);
204
- if (index < 0) throw new Error(`handoff not found: ${sanitizedId}`);
205
- const at = nowIso(options);
206
- const item: HandoffItem = {
207
- ...store.items[index],
208
- ...patch,
209
- status,
210
- updatedAt: at,
211
- };
212
- const items = [...store.items];
213
- items[index] = item;
214
- writeHandoffInboxStore(options, { schemaVersion: 1, updatedAt: at, items });
215
- return item;
216
- });
413
+ if (!usesCanonicalUserRequestStore(options)) {
414
+ throw new Error('HANDOFF_LEGACY_STORE_READ_ONLY: legacy Handoff records are migration input only');
415
+ }
416
+ migrateLegacyHandoffInbox(options);
417
+ const request = requestForHandoffId(options, sanitizedId);
418
+ if (!request) throw new Error(`handoff not found: ${sanitizedId}`);
419
+ if (status === 'acknowledged') return projectUserRequest(request, options.repoId);
420
+ const resolved = request.status === 'pending'
421
+ ? resolveUserRequest(options.controllerHome, {
422
+ requestId: request.requestId,
423
+ decision: patch.decision?.trim() || status,
424
+ resolvedBy: patch.resolver?.trim() || 'system',
425
+ })
426
+ : request;
427
+ return projectUserRequest(resolved, options.repoId);
217
428
  }
218
429
 
219
430
  export function acknowledgeHandoffItem(options: HandoffInboxStoreOptions, id: string): HandoffItem {
@@ -225,16 +436,9 @@ export function resolveHandoffItem(
225
436
  id: string,
226
437
  input?: ResolveHandoffInput,
227
438
  ): HandoffItem {
228
- if (!input?.decision?.trim() || !input?.resolver?.trim()) {
229
- // Backward-compatible path used by older callers; prefer explicit decision + resolver.
230
- return setHandoffStatus(options, id, 'resolved', {
231
- decision: input?.decision?.trim() || 'resolved',
232
- resolver: input?.resolver?.trim() || 'system',
233
- });
234
- }
235
439
  return setHandoffStatus(options, id, 'resolved', {
236
- decision: input.decision.trim().slice(0, 1_000),
237
- resolver: input.resolver.trim().slice(0, 200),
440
+ decision: input?.decision?.trim().slice(0, 1_000) || 'resolved',
441
+ resolver: input?.resolver?.trim().slice(0, 200) || 'system',
238
442
  });
239
443
  }
240
444
 
@@ -1,7 +1,6 @@
1
1
  export * from './types';
2
2
  export * from './handoff-inbox-store';
3
3
  export * from '../../../../packages/kernel/work/api/index';
4
- export * from './work-task-projection';
5
4
  export * from './work-continuation';
6
5
  export * from '../../../../packages/kernel/controller/api/index';
7
6
  export * from './plan-contract-store';
@@ -155,13 +155,12 @@ export function statusLabelForPhase(phase: UserFacingPhase): string {
155
155
  function defaultNextActions(phase: UserFacingPhase, jobId?: string, errorClass?: UserFacingErrorClass): SuggestedNextAction[] {
156
156
  if (phase === 'queued' || phase === 'running' || phase === 'waiting') {
157
157
  return [{
158
- label: '查看任务状态',
159
- tool: 'rh_work',
160
- operation: 'continue',
161
- payload: jobId ? { work_id: jobId } : undefined,
158
+ label: '查看运行状态',
159
+ tool: 'rh_status',
160
+ operation: 'get',
162
161
  risk: 'readonly',
163
162
  confidence: 'high',
164
- reason: '轮询或继续查看当前执行状态。',
163
+ reason: '读取当前运行事实,不通过 Work lifecycle 操作轮询执行。',
165
164
  }];
166
165
  }
167
166
  if (phase === 'failed' || phase === 'timed_out') {
@@ -433,25 +432,23 @@ export function buildAcceptedQueuedDigest(input: {
433
432
  requestId: input.requestId,
434
433
  suggestedNextActions: [
435
434
  {
436
- label: '等待任务完成',
437
- tool: 'rh_work',
438
- operation: 'continue',
439
- payload: { work_id: input.jobId, wait: true },
435
+ label: '查看任务运行状态',
436
+ tool: 'rh_status',
437
+ operation: 'get',
440
438
  risk: 'readonly',
441
439
  confidence: 'high',
442
- reason: '对长时间任务使用 wait/work_get 获取终态摘要。',
440
+ reason: '长时间执行由 Process/Runtime 自己持有;状态读取不推进 Work lifecycle。',
443
441
  },
444
442
  ...defaultNextActions('queued', input.jobId),
445
443
  ],
446
444
  nextActions: [
447
445
  {
448
- label: '等待任务完成',
449
- tool: 'rh_work',
450
- operation: 'continue',
451
- payload: { work_id: input.jobId, wait: true },
446
+ label: '查看任务运行状态',
447
+ tool: 'rh_status',
448
+ operation: 'get',
452
449
  risk: 'readonly',
453
450
  confidence: 'high',
454
- reason: '对长时间任务使用 wait/work_get 获取终态摘要。',
451
+ reason: '长时间执行由 Process/Runtime 自己持有;状态读取不推进 Work lifecycle。',
455
452
  },
456
453
  ...defaultNextActions('queued', input.jobId),
457
454
  ],