@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,14 +1,41 @@
1
1
  import { createHash, randomUUID, timingSafeEqual } from 'crypto';
2
2
  import { join } from 'path';
3
- import { repositoryControllerRoot } from '../../../../src/cli/repositories/controller-home';
3
+ import { FORGE_INSTANCE_SCOPE_KEY, repositoryControllerRoot } from '../../../../src/cli/repositories/controller-home';
4
4
  import { withControllerLock } from '../../../../src/cli/repositories/locks';
5
- import { peekExecutionSession } from '../../../../src/runtime/control-plane/execution/session-store';
5
+ import {
6
+ peekExecutionSession,
7
+ peekExecutionSessionWithinTransaction,
8
+ } from '../../../../src/runtime/control-plane/execution/session-store';
6
9
  import { readJsonFile } from '../../../../src/runtime/shared/json-files';
7
- import { readControlPlaneRecord, readOrImportControlPlaneRecord, writeControlPlaneRecord } from '../../../../src/runtime/control-plane/persistence/sqlite-store';
8
- import { getWorkContract, isTerminalWorkContractStatus } from '../../work/api/index';
10
+ import {
11
+ readControlPlaneRecord,
12
+ readControlPlaneRecordWithinTransaction,
13
+ writeControlPlaneRecord,
14
+ writeControlPlaneRecordWithinTransaction,
15
+ type SqliteDatabase,
16
+ } from '../../../../src/runtime/control-plane/persistence/sqlite-store';
9
17
  import { type ControllerSession, type ControllerSessionStore, type ControllerType } from '../domain/types';
18
+ import { getWorkContract, semanticWorkState } from '../../work/api/index';
10
19
 
11
- export interface ControllerSessionStoreOptions { controllerHome: string; repoId: string; now?: () => string; }
20
+ export interface ControllerSessionStoreOptions {
21
+ controllerHome: string;
22
+ /** Legacy repository provenance/migration hint only; canonical ControllerSession state is ForgeInstance-scoped. */
23
+ repoId: string;
24
+ now?: () => string;
25
+ }
26
+
27
+ const SESSION_STORE_NAMESPACE = 'controller_session_claim_store';
28
+ const SESSION_STORE_KEY = 'index';
29
+ const SESSION_STORE_SCHEMA_VERSION = 1;
30
+
31
+ function assertControllerWorkClaimable(options: ControllerSessionStoreOptions, workId: string): void {
32
+ const work = getWorkContract({ controllerHome: options.controllerHome, repoId: options.repoId }, workId);
33
+ if (!work) return;
34
+ const state = semanticWorkState(work);
35
+ if (state !== 'open') throw new Error(`WORK_CONTROLLER_CLAIM_TERMINAL: ${workId}:${state}`);
36
+ }
37
+
38
+ export type ClaimedControllerSession = ControllerSession & { claimGeneration: number };
12
39
 
13
40
  export interface ControllerSessionClaimInput {
14
41
  workId: string;
@@ -36,23 +63,70 @@ function path(options: ControllerSessionStoreOptions): string {
36
63
 
37
64
  function now(options: ControllerSessionStoreOptions): string { return options.now?.() ?? new Date().toISOString(); }
38
65
 
39
- function read(options: ControllerSessionStoreOptions): ControllerSessionStore {
40
- const legacyPath = path(options);
41
- return readOrImportControlPlaneRecord<ControllerSessionStore>(options.controllerHome, {
42
- namespace: 'controller_session_claim_store',
43
- scope: options.repoId,
44
- key: 'index',
66
+ function legacyStore(options: ControllerSessionStoreOptions): ControllerSessionStore {
67
+ const sqlite = readControlPlaneRecord<ControllerSessionStore>(
68
+ options.controllerHome,
69
+ SESSION_STORE_NAMESPACE,
70
+ options.repoId,
71
+ SESSION_STORE_KEY,
72
+ )?.value;
73
+ if (sqlite) return sqlite;
74
+ return readJsonFile<ControllerSessionStore>(path(options), {
75
+ schemaVersion: 1,
76
+ updatedAt: now(options),
77
+ sessions: [],
78
+ });
79
+ }
80
+
81
+ function mergeSessionStores(
82
+ canonical: ControllerSessionStore,
83
+ legacy: ControllerSessionStore,
84
+ ): ControllerSessionStore {
85
+ const sessions = new Map(canonical.sessions.map((session) => [session.workId, session]));
86
+ for (const candidate of legacy.sessions) {
87
+ const existing = sessions.get(candidate.workId);
88
+ if (!existing) {
89
+ sessions.set(candidate.workId, candidate);
90
+ continue;
91
+ }
92
+ if (JSON.stringify(existing) === JSON.stringify(candidate)) continue;
93
+ const existingGeneration = existing.claimGeneration ?? 0;
94
+ const candidateGeneration = candidate.claimGeneration ?? 0;
95
+ const existingClaimedAt = Date.parse(existing.claimedAt);
96
+ const candidateClaimedAt = Date.parse(candidate.claimedAt);
97
+ if (existingGeneration > candidateGeneration
98
+ || (existingGeneration === candidateGeneration
99
+ && Number.isFinite(existingClaimedAt)
100
+ && Number.isFinite(candidateClaimedAt)
101
+ && existingClaimedAt > candidateClaimedAt)) {
102
+ // Canonical state has advanced since the read-only legacy snapshot.
103
+ continue;
104
+ }
105
+ throw new Error(`CONTROLLER_SESSION_ID_COLLISION: ${candidate.workId}`);
106
+ }
107
+ return {
45
108
  schemaVersion: 1,
46
- readLegacy: () => readJsonFile<ControllerSessionStore>(legacyPath, { schemaVersion: 1, updatedAt: now(options), sessions: [] }),
47
- })?.value ?? { schemaVersion: 1, updatedAt: now(options), sessions: [] };
109
+ updatedAt: canonical.updatedAt >= legacy.updatedAt ? canonical.updatedAt : legacy.updatedAt,
110
+ sessions: [...sessions.values()],
111
+ };
112
+ }
113
+
114
+ function read(options: ControllerSessionStoreOptions): ControllerSessionStore {
115
+ const canonical = readControlPlaneRecord<ControllerSessionStore>(
116
+ options.controllerHome,
117
+ SESSION_STORE_NAMESPACE,
118
+ FORGE_INSTANCE_SCOPE_KEY,
119
+ SESSION_STORE_KEY,
120
+ )?.value ?? { schemaVersion: 1 as const, updatedAt: now(options), sessions: [] };
121
+ return mergeSessionStores(canonical, legacyStore(options));
48
122
  }
49
123
 
50
124
  function write(options: ControllerSessionStoreOptions, store: ControllerSessionStore): void {
51
125
  writeControlPlaneRecord(options.controllerHome, {
52
- namespace: 'controller_session_claim_store',
53
- scope: options.repoId,
54
- key: 'index',
55
- schemaVersion: 1,
126
+ namespace: SESSION_STORE_NAMESPACE,
127
+ scope: FORGE_INSTANCE_SCOPE_KEY,
128
+ key: SESSION_STORE_KEY,
129
+ schemaVersion: SESSION_STORE_SCHEMA_VERSION,
56
130
  value: store,
57
131
  action: 'controller_session_claim_write',
58
132
  });
@@ -67,18 +141,42 @@ interface RetainedControllerSessionRecord {
67
141
  releasedAt?: string;
68
142
  }
69
143
 
144
+ function retainedControllerSessionRecord(
145
+ options: ControllerSessionStoreOptions,
146
+ session: ControllerSession,
147
+ releasedAt?: string,
148
+ ): RetainedControllerSessionRecord {
149
+ const retainedAt = now(options);
150
+ return { schemaVersion: 1, session, retainedAt, ...(releasedAt ? { releasedAt } : {}) };
151
+ }
152
+
70
153
  function persistRetainedControllerSession(
71
154
  options: ControllerSessionStoreOptions,
72
155
  session: ControllerSession,
73
156
  releasedAt?: string,
74
157
  ): void {
75
- const retainedAt = now(options);
76
158
  writeControlPlaneRecord(options.controllerHome, {
77
159
  namespace: RETAINED_SESSION_NAMESPACE,
78
- scope: options.repoId,
160
+ scope: FORGE_INSTANCE_SCOPE_KEY,
161
+ key: session.workId,
162
+ schemaVersion: 1,
163
+ value: retainedControllerSessionRecord(options, session, releasedAt),
164
+ action: releasedAt ? 'controller_session_identity_released' : 'controller_session_identity_retained',
165
+ });
166
+ }
167
+
168
+ function persistRetainedControllerSessionWithinTransaction(
169
+ database: SqliteDatabase,
170
+ options: ControllerSessionStoreOptions,
171
+ session: ControllerSession,
172
+ releasedAt?: string,
173
+ ): void {
174
+ writeControlPlaneRecordWithinTransaction(database, {
175
+ namespace: RETAINED_SESSION_NAMESPACE,
176
+ scope: FORGE_INSTANCE_SCOPE_KEY,
79
177
  key: session.workId,
80
178
  schemaVersion: 1,
81
- value: { schemaVersion: 1, session, retainedAt, ...(releasedAt ? { releasedAt } : {}) } satisfies RetainedControllerSessionRecord,
179
+ value: retainedControllerSessionRecord(options, session, releasedAt),
82
180
  action: releasedAt ? 'controller_session_identity_released' : 'controller_session_identity_retained',
83
181
  });
84
182
  }
@@ -88,14 +186,32 @@ export function getRetainedControllerSession(
88
186
  options: ControllerSessionStoreOptions,
89
187
  workId: string,
90
188
  ): ControllerSession | undefined {
91
- const retained = readControlPlaneRecord<RetainedControllerSessionRecord>(
189
+ const canonical = readControlPlaneRecord<RetainedControllerSessionRecord>(
190
+ options.controllerHome,
191
+ RETAINED_SESSION_NAMESPACE,
192
+ FORGE_INSTANCE_SCOPE_KEY,
193
+ workId,
194
+ )?.value.session;
195
+ const legacy = readControlPlaneRecord<RetainedControllerSessionRecord>(
92
196
  options.controllerHome,
93
197
  RETAINED_SESSION_NAMESPACE,
94
198
  options.repoId,
95
199
  workId,
96
200
  )?.value.session;
97
- if (retained) return retained;
98
- return read(options).sessions.find((entry) => entry.workId === workId);
201
+ if (canonical && legacy && JSON.stringify(canonical) !== JSON.stringify(legacy)) {
202
+ const canonicalGeneration = canonical.claimGeneration ?? 0;
203
+ const legacyGeneration = legacy.claimGeneration ?? 0;
204
+ const canonicalClaimedAt = Date.parse(canonical.claimedAt);
205
+ const legacyClaimedAt = Date.parse(legacy.claimedAt);
206
+ if (!(canonicalGeneration > legacyGeneration
207
+ || (canonicalGeneration === legacyGeneration
208
+ && Number.isFinite(canonicalClaimedAt)
209
+ && Number.isFinite(legacyClaimedAt)
210
+ && canonicalClaimedAt > legacyClaimedAt))) {
211
+ throw new Error(`CONTROLLER_SESSION_ID_COLLISION: ${workId}`);
212
+ }
213
+ }
214
+ return canonical ?? legacy ?? read(options).sessions.find((entry) => entry.workId === workId);
99
215
  }
100
216
 
101
217
  const DEFAULT_CONTROLLER_RECOVERY_GRACE_MS = 5 * 60_000;
@@ -150,19 +266,18 @@ function assertIdentity(input: ControllerSessionClaimInput): void {
150
266
  }
151
267
  }
152
268
 
153
- function assertWorkClaimable(options: ControllerSessionStoreOptions, workId: string): void {
154
- const work = getWorkContract({ controllerHome: options.controllerHome, repoId: options.repoId }, workId);
155
- if (work && isTerminalWorkContractStatus(work.status)) {
156
- throw new Error(`WORK_CONTROLLER_CLAIM_TERMINAL: ${work.workId}:${work.status}`);
157
- }
158
- }
269
+ /**
270
+ * Compatibility no-op. ControllerSession is mechanical dispatch/reattachment
271
+ * state and does not decide whether semantic Work is open or terminal.
272
+ */
273
+ export function assertControllerSessionWorkClaimable(_options: ControllerSessionStoreOptions, _workId: string): void {}
159
274
 
160
275
  function claimedSession(
161
276
  options: ControllerSessionStoreOptions,
162
277
  input: ControllerSessionClaimInput,
163
278
  claimedAt: string,
164
279
  previous?: ControllerSession,
165
- ): ControllerSession {
280
+ ): ClaimedControllerSession {
166
281
  const leaseExpiresAt = new Date(
167
282
  Date.parse(claimedAt) + Math.max(1_000, Math.min(input.leaseMs ?? DEFAULT_CONTROLLER_LEASE_MS, MAX_CONTROLLER_LEASE_MS)),
168
283
  ).toISOString();
@@ -199,12 +314,12 @@ function assertExpectedGeneration(input: ControllerSessionClaimInput, current: C
199
314
  }
200
315
  }
201
316
 
202
- function persistClaim(
317
+ function preparedClaim(
203
318
  options: ControllerSessionStoreOptions,
204
319
  store: ControllerSessionStore,
205
320
  input: ControllerSessionClaimInput,
206
321
  previous?: ControllerSession,
207
- ): ControllerSession {
322
+ ): { claimedAt: string; session: ClaimedControllerSession; nextStore: ControllerSessionStore } {
208
323
  const claimedAt = now(options);
209
324
  const claimedAtMs = Date.parse(claimedAt);
210
325
  const session = claimedSession(options, input, claimedAt, previous);
@@ -212,9 +327,68 @@ function persistClaim(
212
327
  ...store.sessions.filter((entry) => entry.workId !== input.workId && Date.parse(entry.leaseExpiresAt) > claimedAtMs),
213
328
  session,
214
329
  ];
215
- write(options, { schemaVersion: 1, updatedAt: claimedAt, sessions });
216
- persistRetainedControllerSession(options, session);
217
- return session;
330
+ return { claimedAt, session, nextStore: { schemaVersion: 1, updatedAt: claimedAt, sessions } };
331
+ }
332
+
333
+ function persistClaim(
334
+ options: ControllerSessionStoreOptions,
335
+ store: ControllerSessionStore,
336
+ input: ControllerSessionClaimInput,
337
+ previous?: ControllerSession,
338
+ ): ClaimedControllerSession {
339
+ const prepared = preparedClaim(options, store, input, previous);
340
+ write(options, prepared.nextStore);
341
+ persistRetainedControllerSession(options, prepared.session);
342
+ return prepared.session;
343
+ }
344
+
345
+ function readSessionStoreWithinTransaction(
346
+ database: SqliteDatabase,
347
+ options: ControllerSessionStoreOptions,
348
+ ) {
349
+ let current = readControlPlaneRecordWithinTransaction<ControllerSessionStore>(
350
+ database, SESSION_STORE_NAMESPACE, FORGE_INSTANCE_SCOPE_KEY, SESSION_STORE_KEY,
351
+ );
352
+ const legacySqlite = readControlPlaneRecordWithinTransaction<ControllerSessionStore>(
353
+ database, SESSION_STORE_NAMESPACE, options.repoId, SESSION_STORE_KEY,
354
+ )?.value;
355
+ const legacy = legacySqlite ?? readJsonFile<ControllerSessionStore>(path(options), {
356
+ schemaVersion: 1,
357
+ updatedAt: now(options),
358
+ sessions: [],
359
+ });
360
+ if (current) return { ...current, value: mergeSessionStores(current.value, legacy) };
361
+ current = writeControlPlaneRecordWithinTransaction(database, {
362
+ namespace: SESSION_STORE_NAMESPACE,
363
+ scope: FORGE_INSTANCE_SCOPE_KEY,
364
+ key: SESSION_STORE_KEY,
365
+ schemaVersion: SESSION_STORE_SCHEMA_VERSION,
366
+ value: legacy,
367
+ action: 'legacy_controller_session_import',
368
+ expectedRevision: null,
369
+ });
370
+ return current;
371
+ }
372
+
373
+ function persistClaimWithinTransaction(
374
+ database: SqliteDatabase,
375
+ options: ControllerSessionStoreOptions,
376
+ storeRecord: ReturnType<typeof readSessionStoreWithinTransaction>,
377
+ input: ControllerSessionClaimInput,
378
+ previous?: ControllerSession,
379
+ ): ClaimedControllerSession {
380
+ const prepared = preparedClaim(options, storeRecord.value, input, previous);
381
+ writeControlPlaneRecordWithinTransaction(database, {
382
+ namespace: SESSION_STORE_NAMESPACE,
383
+ scope: FORGE_INSTANCE_SCOPE_KEY,
384
+ key: SESSION_STORE_KEY,
385
+ schemaVersion: SESSION_STORE_SCHEMA_VERSION,
386
+ value: prepared.nextStore,
387
+ action: 'controller_session_claim_write',
388
+ expectedRevision: storeRecord.revision,
389
+ });
390
+ persistRetainedControllerSessionWithinTransaction(database, options, prepared.session);
391
+ return prepared.session;
218
392
  }
219
393
 
220
394
  export function getControllerSession(options: ControllerSessionStoreOptions, workId: string): ControllerSession | undefined {
@@ -371,7 +545,7 @@ export function withControllerSessionTerminalizationFence<T>(
371
545
  ): ControllerTerminalizationFenceResult<T> {
372
546
  return withControllerLock(
373
547
  options.controllerHome,
374
- { scope: 'task', repoId: options.repoId, taskId: `controller-session-${input.workId}` },
548
+ { scope: 'global', resource: 'controller-session-store' },
375
549
  input.actor,
376
550
  () => {
377
551
  const owner = activeSession(read(options), input.workId, optionsNowMs(options));
@@ -404,7 +578,7 @@ export function releaseControllerSessionWithAuthority(
404
578
  ): ControllerTerminalizationFenceResult<void> {
405
579
  return withControllerLock(
406
580
  options.controllerHome,
407
- { scope: 'task', repoId: options.repoId, taskId: `controller-session-${input.workId}` },
581
+ { scope: 'global', resource: 'controller-session-store' },
408
582
  input.actor,
409
583
  () => {
410
584
  const store = read(options);
@@ -442,14 +616,14 @@ export function releaseObservedControllerSession(
442
616
  export function claimControllerSession(
443
617
  options: ControllerSessionStoreOptions,
444
618
  input: ControllerSessionClaimInput,
445
- ): ControllerSession {
619
+ ): ClaimedControllerSession {
446
620
  assertIdentity(input);
447
621
  return withControllerLock(
448
622
  options.controllerHome,
449
- { scope: 'task', repoId: options.repoId, taskId: `controller-session-${input.workId}` },
623
+ { scope: 'global', resource: 'controller-session-store' },
450
624
  `controller-claim:${input.controllerId}:${input.sessionId}`,
451
625
  () => {
452
- assertWorkClaimable(options, input.workId);
626
+ assertControllerWorkClaimable(options, input.workId);
453
627
  const store = read(options);
454
628
  const current = activeSession(store, input.workId, optionsNowMs(options));
455
629
  const previous = current ?? store.sessions
@@ -470,45 +644,86 @@ export function claimControllerSession(
470
644
  * A same-principal session rotation therefore preserves ownership generation;
471
645
  * a controller-epoch change is recovery and advances the generation fence.
472
646
  */
647
+ function resumableControllerSessionPrevious(
648
+ options: ControllerSessionStoreOptions,
649
+ store: ControllerSessionStore,
650
+ input: ControllerSessionClaimInput & { principalId: string; controllerInstanceId: string },
651
+ database?: SqliteDatabase,
652
+ ): ControllerSession | undefined {
653
+ assertControllerWorkClaimable(options, input.workId);
654
+ const currentNowMs = optionsNowMs(options);
655
+ const current = activeSession(store, input.workId, currentNowMs);
656
+ assertExpectedGeneration(input, current);
657
+ if (!current) {
658
+ return store.sessions
659
+ .filter((entry) => entry.workId === input.workId)
660
+ .sort((left, right) => (right.claimGeneration ?? 0) - (left.claimGeneration ?? 0))[0];
661
+ }
662
+ const explicitPrincipal = current.principalId?.trim();
663
+ const priorExecution = explicitPrincipal
664
+ ? undefined
665
+ : database
666
+ ? peekExecutionSessionWithinTransaction(database, options.controllerHome, current.sessionId)
667
+ : peekExecutionSession(options.controllerHome, current.sessionId);
668
+ const currentPrincipal = explicitPrincipal || priorExecution?.principalId?.trim() || current.controllerId;
669
+ const staleRecoveryAllowed = input.allowStaleRecovery === true
670
+ && input.expectedClaimGeneration !== undefined
671
+ && !sessionBlocksRecovery(options, current, { nowMs: currentNowMs });
672
+ if (currentPrincipal !== input.principalId.trim() && !staleRecoveryAllowed) {
673
+ throw new Error(`WORK_CONTROLLER_PRINCIPAL_MISMATCH: ${input.workId} is owned by another authenticated principal`);
674
+ }
675
+ if (current.controllerId !== input.controllerId && !staleRecoveryAllowed) {
676
+ throw new Error(`WORK_ALREADY_CLAIMED: ${input.workId} is owned by ${current.controllerId}`);
677
+ }
678
+ if (current.controllerType !== input.controllerType && !staleRecoveryAllowed) {
679
+ throw new Error(`WORK_CONTROLLER_TYPE_MISMATCH: ${input.workId} is owned by ${current.controllerType}`);
680
+ }
681
+ return current;
682
+ }
683
+
684
+ export function withControllerSessionMutationLock<T>(
685
+ options: ControllerSessionStoreOptions,
686
+ workId: string,
687
+ actor: string,
688
+ operation: () => T,
689
+ ): T {
690
+ return withControllerLock(
691
+ options.controllerHome,
692
+ { scope: 'global', resource: 'controller-session-store' },
693
+ actor,
694
+ operation,
695
+ );
696
+ }
697
+
698
+ /** Transaction-aware resume used only by higher-level Controller claim orchestration while the canonical session lock is held. */
699
+ export function resumeControllerSessionWithinTransaction(
700
+ database: SqliteDatabase,
701
+ options: ControllerSessionStoreOptions,
702
+ input: ControllerSessionClaimInput & { principalId: string; controllerInstanceId: string },
703
+ ): ClaimedControllerSession {
704
+ assertIdentity(input);
705
+ if (!input.principalId.trim() || !input.controllerInstanceId.trim()) throw new Error('CONTROLLER_RESUME_AUTHORITY_REQUIRED');
706
+ const storeRecord = readSessionStoreWithinTransaction(database, options);
707
+ const previous = resumableControllerSessionPrevious(options, storeRecord.value, input, database);
708
+ return persistClaimWithinTransaction(database, options, storeRecord, input, previous);
709
+ }
710
+
473
711
  export function resumeControllerSession(
474
712
  options: ControllerSessionStoreOptions,
475
713
  input: ControllerSessionClaimInput & { principalId: string; controllerInstanceId: string },
476
- ): ControllerSession {
714
+ ): ClaimedControllerSession {
477
715
  assertIdentity(input);
478
716
  if (!input.principalId.trim() || !input.controllerInstanceId.trim()) {
479
717
  throw new Error('CONTROLLER_RESUME_AUTHORITY_REQUIRED');
480
718
  }
481
- return withControllerLock(
482
- options.controllerHome,
483
- { scope: 'task', repoId: options.repoId, taskId: `controller-session-${input.workId}` },
719
+ return withControllerSessionMutationLock(
720
+ options,
721
+ input.workId,
484
722
  `controller-resume:${input.controllerId}:${input.sessionId}`,
485
723
  () => {
486
- assertWorkClaimable(options, input.workId);
487
724
  const store = read(options);
488
- const currentNowMs = optionsNowMs(options);
489
- const current = activeSession(store, input.workId, currentNowMs);
490
- assertExpectedGeneration(input, current);
491
- if (!current) {
492
- const previous = store.sessions
493
- .filter((entry) => entry.workId === input.workId)
494
- .sort((left, right) => (right.claimGeneration ?? 0) - (left.claimGeneration ?? 0))[0];
495
- return persistClaim(options, store, input, previous);
496
- }
497
- const priorExecution = peekExecutionSession(options.controllerHome, current.sessionId);
498
- const currentPrincipal = current.principalId?.trim() || priorExecution?.principalId?.trim() || current.controllerId;
499
- const staleRecoveryAllowed = input.allowStaleRecovery === true
500
- && input.expectedClaimGeneration !== undefined
501
- && !sessionBlocksRecovery(options, current, { nowMs: currentNowMs });
502
- if (currentPrincipal !== input.principalId.trim() && !staleRecoveryAllowed) {
503
- throw new Error(`WORK_CONTROLLER_PRINCIPAL_MISMATCH: ${input.workId} is owned by another authenticated principal`);
504
- }
505
- if (current.controllerId !== input.controllerId && !staleRecoveryAllowed) {
506
- throw new Error(`WORK_ALREADY_CLAIMED: ${input.workId} is owned by ${current.controllerId}`);
507
- }
508
- if (current.controllerType !== input.controllerType && !staleRecoveryAllowed) {
509
- throw new Error(`WORK_CONTROLLER_TYPE_MISMATCH: ${input.workId} is owned by ${current.controllerType}`);
510
- }
511
- return persistClaim(options, store, input, current);
725
+ const previous = resumableControllerSessionPrevious(options, store, input);
726
+ return persistClaim(options, store, input, previous);
512
727
  },
513
728
  );
514
729
  }
@@ -554,9 +769,20 @@ export function bindControllerSessionToCurrentRuntime(
554
769
  throw new Error(`WORK_CONTROLLER_INSTANCE_MISMATCH: ${input.workId}`);
555
770
  }
556
771
  }
557
- if (ownerInstanceId === requestedInstanceId && current.sessionId === input.sessionId) return current;
772
+ const requestedAuthorityDigest = input.authorityDigest?.trim() || '';
773
+ const currentAuthorityDigest = current.authorityDigest?.trim() || '';
774
+ if (
775
+ ownerInstanceId === requestedInstanceId
776
+ && current.sessionId === input.sessionId
777
+ && (!requestedAuthorityDigest || requestedAuthorityDigest === currentAuthorityDigest)
778
+ ) return current;
779
+ // The opaque Work capability belongs to durable ownership, not to one
780
+ // transport or Runtime process. A positively-current Runtime migration keeps
781
+ // the same digest while claim generation fences the new controller epoch.
782
+ const preservedAuthorityDigest = input.authorityDigest?.trim() || current.authorityDigest?.trim() || undefined;
558
783
  return resumeControllerSession(options, {
559
784
  ...input,
785
+ ...(preservedAuthorityDigest ? { authorityDigest: preservedAuthorityDigest } : {}),
560
786
  expectedClaimGeneration: current.claimGeneration,
561
787
  });
562
788
  }
@@ -564,7 +790,7 @@ export function bindControllerSessionToCurrentRuntime(
564
790
  export function releaseControllerSession(options: ControllerSessionStoreOptions, workId: string, controllerId: string): void {
565
791
  withControllerLock(
566
792
  options.controllerHome,
567
- { scope: 'task', repoId: options.repoId, taskId: `controller-session-${workId}` },
793
+ { scope: 'global', resource: 'controller-session-store' },
568
794
  `controller-release:${controllerId}`,
569
795
  () => {
570
796
  const store = read(options);
@@ -8,6 +8,8 @@ export interface ControllerHostResumeResult {
8
8
  waitForUser?: boolean;
9
9
  /** Durable user-action Handoff created by the provider adapter when waitForUser=true. */
10
10
  handoffId?: string;
11
+ /** Known non-ambiguous provider failure that may retry the same semantic round under its existing failure budget. */
12
+ recoverable?: boolean;
11
13
  }
12
14
 
13
15
  /** Provider-neutral continuation port. Implementations live in adapters/*. */
@@ -1,5 +1,15 @@
1
1
  export * from '../domain/types';
2
2
  export * from '../domain/scope';
3
+ export * from '../domain/grant';
3
4
  export * from '../application/identity-service';
4
5
  export * from '../domain/workspace';
5
6
  export * from '../domain/semantic-sync';
7
+ export * from '../infrastructure/grant-store';
8
+ export * from '../domain/user-request';
9
+ export * from '../infrastructure/user-request-store';
10
+ export * from '../domain/owned-resource';
11
+ export * from '../infrastructure/owned-resource-store';
12
+ export * from '../domain/capability-broker';
13
+ export * from '../infrastructure/capability-broker';
14
+ export * from '../domain/activity-projection';
15
+ export * from '../infrastructure/activity-projection-store';
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Canonical Activity Projection Model.
3
+ *
4
+ * GUI work tree is an explicit-link projection of Requirement / Plan / Work,
5
+ * while direct capability activity that has no Work appears in Activity/history
6
+ * rather than being forced into a synthetic Work.
7
+ *
8
+ * Realtime progress comes from Process / Operation / Agent / provider snapshots
9
+ * with observedAt/freshness. History combines semantic revisions with selected
10
+ * immutable receipts and terminal operation events.
11
+ */
12
+
13
+ export interface CapabilityActivityItem {
14
+ activityId: string;
15
+ capabilityId: string;
16
+ kind: 'direct_execution' | 'agent_delegation' | 'scheduled_trigger' | 'work_bound';
17
+ targetScope: string;
18
+ principalId: string;
19
+ associatedWorkId?: string;
20
+ status: 'running' | 'completed' | 'failed' | 'cancelled';
21
+ startedAt: string;
22
+ completedAt?: string;
23
+ summary?: string;
24
+ receiptRef?: string;
25
+ }
26
+
27
+ export interface WorkTreeProjectionNode {
28
+ type: 'requirement' | 'plan' | 'work';
29
+ id: string;
30
+ title?: string;
31
+ status: string;
32
+ revision: number;
33
+ updatedAt: string;
34
+ parentId?: string;
35
+ children?: WorkTreeProjectionNode[];
36
+ }
37
+
38
+ export interface UnifiedActivityView {
39
+ workTree: WorkTreeProjectionNode[];
40
+ directActivities: CapabilityActivityItem[];
41
+ observedAt: string;
42
+ freshnessMs: number;
43
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Canonical Mode-Free Capability Broker Types and Contracts.
3
+ *
4
+ * Public capabilities (read, search, edit, command, process, git, workspace,
5
+ * browser, computer, plugin, API, agent, schedule, release, recovery)
6
+ * compose without mandatory Requirement/Plan/Work, task-size thresholds,
7
+ * or Direct/GoalWorkloop/Scale mode tokens.
8
+ *
9
+ * Shared invocation conventions:
10
+ * - target / principal
11
+ * - typed arguments
12
+ * - optional expected revision
13
+ * - timeout / cancellation
14
+ * - optional idempotency / request identity
15
+ * - result or typed handle
16
+ */
17
+
18
+ export interface CapabilityTarget {
19
+ scope: 'global' | 'repository' | 'workspace' | 'device' | 'account' | 'provider';
20
+ scopeId?: string;
21
+ repoId?: string;
22
+ }
23
+
24
+ export interface CapabilityInvocationInput<TArgs = Record<string, unknown>> {
25
+ capabilityId: string;
26
+ target: CapabilityTarget;
27
+ principalId: string;
28
+ arguments: TArgs;
29
+ expectedRevision?: number;
30
+ timeoutMs?: number;
31
+ idempotencyKey?: string;
32
+ associatedWorkId?: string;
33
+ }
34
+
35
+ export type CapabilityExecutionKind = 'synchronous' | 'managed_handle' | 'delegated_agent';
36
+
37
+ export interface CapabilityTypedHandle {
38
+ handleId: string;
39
+ capabilityId: string;
40
+ executionKind: CapabilityExecutionKind;
41
+ target: CapabilityTarget;
42
+ status: 'running' | 'completed' | 'failed' | 'cancelled';
43
+ startedAt: string;
44
+ updatedAt: string;
45
+ result?: unknown;
46
+ error?: {
47
+ code: string;
48
+ message: string;
49
+ };
50
+ }
51
+
52
+ export interface CapabilityInvocationResult<TResult = unknown> {
53
+ success: boolean;
54
+ result?: TResult;
55
+ handle?: CapabilityTypedHandle;
56
+ error?: {
57
+ code: string;
58
+ message: string;
59
+ };
60
+ }