@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 { existsSync, lstatSync, opendirSync, statSync, unlinkSync } from 'fs';
2
2
  import { join, relative } from 'path';
3
- import { isTerminalWorkContractStatus, type WorkContract } from '../../../../packages/kernel/work/api/index';
3
+ import { isTerminalSemanticWorkState, type WorkContract } from '../../../../packages/kernel/work/api/index';
4
4
  import { listControlPlaneRecords } from '../../control-plane/persistence/sqlite-store';
5
5
  import { processLogDir } from './store';
6
6
  import { readPersistedCheckResultReceipt } from './check-result';
@@ -50,7 +50,7 @@ export function cleanupPersistedCheckResults(
50
50
  }
51
51
  for (const record of workRecords) {
52
52
  const work = record.value;
53
- if (isTerminalWorkContractStatus(work.status)) continue;
53
+ if (isTerminalSemanticWorkState(work.semanticState)) continue;
54
54
  for (const verification of work.checkRefs ?? []) {
55
55
  const key = verification.receipt?.checkCacheKey?.trim();
56
56
  if (key) protectedCacheKeys.add(key);
@@ -3,6 +3,7 @@ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from '
3
3
  import { dirname, join } from 'path';
4
4
  import { processLogDir } from './store';
5
5
  import type { ManagedProcessRecord } from './types';
6
+ import type { ProcessCheckCompletionReceipt } from './check-receipt';
6
7
 
7
8
  export const STRUCTURED_CHECK_RESULT_PATH_ENV = 'FORGE_CHECK_STRUCTURED_RESULT_PATH';
8
9
  export const MAX_STRUCTURED_CHECK_FAILURE_DETAILS = 32;
@@ -110,7 +111,17 @@ export function readPersistedCheckResultReceipt(path: string | undefined): Persi
110
111
  if (!path || !existsSync(path)) return undefined;
111
112
  try {
112
113
  const value = JSON.parse(readFileSync(path, 'utf8')) as PersistedCheckResultReceipt;
113
- if (value?.schemaVersion !== 1 || typeof value.receiptId !== 'string' || typeof value.cacheKey !== 'string') return undefined;
114
+ if (
115
+ value?.schemaVersion !== 1
116
+ || typeof value.receiptId !== 'string'
117
+ || typeof value.checkId !== 'string'
118
+ || typeof value.cacheKey !== 'string'
119
+ || typeof value.ok !== 'boolean'
120
+ || typeof value.status !== 'number'
121
+ || typeof value.timedOut !== 'boolean'
122
+ || typeof value.executedAt !== 'string'
123
+ || (value.failureClass !== undefined && value.failureClass !== 'acceptance_failure' && value.failureClass !== 'infrastructure_failure')
124
+ ) return undefined;
114
125
  if (value.failureEvidence !== undefined && !isStructuredCheckFailureEvidence(value.failureEvidence)) return undefined;
115
126
  return value;
116
127
  } catch {
@@ -128,6 +139,9 @@ export interface PersistedCheckTerminalEvidence {
128
139
  state: PersistedCheckTerminalEvidenceState;
129
140
  failureClass?: PersistedCheckResultReceipt['failureClass'];
130
141
  failureEvidence?: StructuredCheckFailureEvidence;
142
+ semanticOk?: boolean;
143
+ semanticStatus?: number;
144
+ semanticTimedOut?: boolean;
131
145
  warning?: string;
132
146
  infrastructureReason?: string;
133
147
  }
@@ -173,6 +187,9 @@ export function classifyTerminalCheckEvidence(
173
187
  */
174
188
  export interface LegacyCheckEvidenceLike {
175
189
  cacheKey?: string;
190
+ ok?: boolean;
191
+ status?: number;
192
+ timedOut?: boolean;
176
193
  failureClass?: PersistedCheckResultReceipt['failureClass'];
177
194
  failureEvidence?: StructuredCheckFailureEvidence;
178
195
  }
@@ -207,6 +224,93 @@ export function classifyPersistedCheckTerminalEvidence(
207
224
  ...classified,
208
225
  failureClass: structuredMatches ? structured?.failureClass : legacy?.failureClass,
209
226
  failureEvidence: structuredMatches ? structured?.failureEvidence : legacy?.failureEvidence,
227
+ semanticOk: structuredMatches ? structured?.ok : legacy?.ok,
228
+ semanticStatus: structuredMatches ? structured?.status : legacy?.status,
229
+ semanticTimedOut: structuredMatches ? structured?.timedOut : legacy?.timedOut,
210
230
  }
211
231
  : classified;
212
232
  }
233
+
234
+ export type TerminalCheckVerificationOutcome = 'valid_pass' | 'valid_fail' | 'infrastructure_failure';
235
+
236
+ export interface TerminalCheckVerificationProjection {
237
+ outcome: TerminalCheckVerificationOutcome;
238
+ failureClass?: 'acceptance_failure' | 'infrastructure_failure';
239
+ isAcceptanceFailure: boolean;
240
+ isInfrastructureIssue: boolean;
241
+ boundedStatus: 'pass' | 'fail' | 'infrastructure_failure';
242
+ evidence: PersistedCheckTerminalEvidence;
243
+ infrastructureReason?: string;
244
+ }
245
+
246
+ /**
247
+ * Canonical Failure Contract projection from one exact terminal Check Process
248
+ * plus its semantic Check-result evidence into Work verification truth.
249
+ * Process exit state is necessary evidence, but never acceptance authority by
250
+ * itself. Missing, mismatched, interrupted, infrastructure, or contradictory
251
+ * evidence fails closed as infrastructure_failure.
252
+ */
253
+ export function projectTerminalCheckVerification(
254
+ record: ManagedProcessRecord,
255
+ expectedCheckId: string,
256
+ receipt: ProcessCheckCompletionReceipt,
257
+ options: { legacyEvidence?: LegacyCheckEvidenceLike } = {},
258
+ ): TerminalCheckVerificationProjection {
259
+ const evidence = classifyPersistedCheckTerminalEvidence(record, expectedCheckId, options);
260
+ const semanticContradiction = evidence.state === 'matched' && Boolean(
261
+ (evidence.semanticOk !== undefined && evidence.semanticOk !== receipt.ok)
262
+ || (evidence.semanticTimedOut !== undefined && evidence.semanticTimedOut !== receipt.timedOut)
263
+ || (evidence.semanticOk === true && evidence.semanticStatus !== undefined && evidence.semanticStatus !== 0)
264
+ || (evidence.semanticOk === false && evidence.semanticStatus === 0)
265
+ || (receipt.ok && evidence.failureClass !== undefined)
266
+ || (evidence.semanticOk === true && evidence.failureClass !== undefined)
267
+ || (!receipt.ok && evidence.failureClass === undefined)
268
+ || (evidence.semanticOk === false && evidence.failureClass === undefined)
269
+ );
270
+ const infrastructureReason = evidence.infrastructureReason
271
+ ?? (semanticContradiction ? 'terminal Check Process and semantic result evidence contradict each other' : undefined);
272
+ const infrastructure = receipt.timedOut
273
+ || receipt.cancelled
274
+ || evidence.state !== 'matched'
275
+ || semanticContradiction
276
+ || evidence.failureClass === 'infrastructure_failure';
277
+ if (infrastructure) {
278
+ return {
279
+ outcome: 'infrastructure_failure',
280
+ failureClass: 'infrastructure_failure',
281
+ isAcceptanceFailure: false,
282
+ isInfrastructureIssue: true,
283
+ boundedStatus: 'infrastructure_failure',
284
+ evidence,
285
+ ...(infrastructureReason ? { infrastructureReason } : {}),
286
+ };
287
+ }
288
+ if (receipt.ok) {
289
+ return {
290
+ outcome: 'valid_pass',
291
+ isAcceptanceFailure: false,
292
+ isInfrastructureIssue: false,
293
+ boundedStatus: 'pass',
294
+ evidence,
295
+ };
296
+ }
297
+ if (evidence.failureClass === 'acceptance_failure') {
298
+ return {
299
+ outcome: 'valid_fail',
300
+ failureClass: 'acceptance_failure',
301
+ isAcceptanceFailure: true,
302
+ isInfrastructureIssue: false,
303
+ boundedStatus: 'fail',
304
+ evidence,
305
+ };
306
+ }
307
+ return {
308
+ outcome: 'infrastructure_failure',
309
+ failureClass: 'infrastructure_failure',
310
+ isAcceptanceFailure: false,
311
+ isInfrastructureIssue: true,
312
+ boundedStatus: 'infrastructure_failure',
313
+ evidence,
314
+ infrastructureReason: 'terminal Check failure lacks explicit acceptance-failure evidence',
315
+ };
316
+ }
@@ -2,13 +2,8 @@
2
2
  import { createHash } from 'crypto';
3
3
  import { rmSync } from 'fs';
4
4
  import { resolve } from 'path';
5
- import {
6
- controllerCheckExecutionIdentity,
7
- runControllerCheckAsync,
8
- snapshotControllerCheck,
9
- type ControllerCheckSnapshot,
10
- } from '../../../cli/controller/check-runner';
11
- import { writePersistedCheckResultReceipt } from './check-result';
5
+ import type { ControllerCheckSnapshot } from '../../../cli/controller/check-runner';
6
+ import { materializeManagedWorkspaceDependencies } from '../managed-workspace';
12
7
  import { PROCESS_RUNTIME_RELEASE_CANARY_ARG } from './canary';
13
8
 
14
9
  interface ParsedArgs {
@@ -33,7 +28,6 @@ function requiredValue(argv: string[], flag: string): string {
33
28
  return value;
34
29
  }
35
30
 
36
-
37
31
  function decodeCheckSnapshot(value: string): ControllerCheckSnapshot {
38
32
  let decoded: unknown;
39
33
  try {
@@ -77,6 +71,22 @@ export async function runPersistedCheckSidecar(argv = process.argv.slice(2)): Pr
77
71
  const args = parseArgs(argv);
78
72
  const root = resolve(args.repo);
79
73
  try {
74
+ // A Work verification snapshot is disposable execution state. When exact
75
+ // canonical dependency reuse was unavailable during snapshot construction,
76
+ // establish the candidate's frozen dependency closure inside this Check
77
+ // Process before loading the candidate Check Runner module graph.
78
+ if (args.cleanupRoot && (!args.checkSnapshot || args.checkSnapshot.source === 'package-script')) {
79
+ materializeManagedWorkspaceDependencies(root);
80
+ }
81
+
82
+ const [
83
+ { controllerCheckExecutionIdentity, runControllerCheckAsync, snapshotControllerCheck },
84
+ { writePersistedCheckResultReceipt },
85
+ ] = await Promise.all([
86
+ import('../../../cli/controller/check-runner'),
87
+ import('./check-result'),
88
+ ]);
89
+
80
90
  // New callers carry the exact definition resolved from canonical repository
81
91
  // authority. The fallback keeps older package releases compatible.
82
92
  const snapshot = args.checkSnapshot ?? snapshotControllerCheck(root, args.checkId);
@@ -8,7 +8,10 @@
8
8
  * - Durable: explicit Work/external/release boundaries only.
9
9
  */
10
10
 
11
- import type { RepositoryRecord } from '../../../cli/repositories/types';
11
+ import {
12
+ commandExecutionScopeKey,
13
+ type RepositoryCommandScopeTarget,
14
+ } from '../../../cli/repositories/command-scope';
12
15
  import { classifyRepositoryCommand, fixedShellWrapperCommand, shellSegments, shellWordsPreservingQuotes } from '../../../cli/repositories/command-classifier';
13
16
  import {
14
17
  executeRepositoryCommandAsync,
@@ -38,10 +41,12 @@ import {
38
41
  cancelLightweightProcess,
39
42
  getLightweightProcessHandle,
40
43
  isLightweightProcessId,
44
+ lightweightProcessScopeKey,
41
45
  readLightweightProcessLogs,
42
46
  startLightweightRepositoryCommand,
43
47
  waitForLightweightProcess,
44
48
  } from './lightweight-managed';
49
+ import { isForgeInstanceProcessScopeKey, processScopeKeyForHandle } from './process-scope';
45
50
 
46
51
  export type RepositoryCommandRoute =
47
52
  | 'process_direct'
@@ -51,7 +56,8 @@ export type RepositoryCommandRoute =
51
56
 
52
57
  export interface RepositoryCommandProcessInput {
53
58
  controllerHome: string;
54
- repository: RepositoryRecord;
59
+ /** Repository identity is optional: an arbitrary workspace target carries a workspace scope key. */
60
+ repository: RepositoryCommandScopeTarget;
55
61
  command: string | readonly string[];
56
62
  cwd?: string;
57
63
  timeoutMs?: number;
@@ -64,6 +70,8 @@ export interface RepositoryCommandProcessInput {
64
70
  requestId?: string;
65
71
  workId?: string;
66
72
  commandId?: string;
73
+ /** Authenticated principal recorded with the process handle for principal-bound attachment. */
74
+ principalId?: string;
67
75
  signal?: AbortSignal;
68
76
  /** Explicit unregistered local workspace authority; never inferred from cwd. */
69
77
  allowNonGitWorkspace?: boolean;
@@ -353,9 +361,9 @@ export async function executeRepositoryCommandViaProcessRuntime(
353
361
  throw new Error('EXECUTION_IDENTITY_REQUIRED: repository command process path requires an immutable executionIdentity');
354
362
  }
355
363
  const executionIdentity = input.executionIdentity;
356
- if (executionIdentity.repositoryId !== input.repository.repoId) {
364
+ if (executionIdentity.repositoryId !== commandExecutionScopeKey(input.repository)) {
357
365
  throw new Error(
358
- `EXECUTION_IDENTITY_MISMATCH: repository ${input.repository.repoId} differs from identity ${executionIdentity.repositoryId}`,
366
+ `EXECUTION_IDENTITY_MISMATCH: repository ${commandExecutionScopeKey(input.repository)} differs from identity ${executionIdentity.repositoryId}`,
359
367
  );
360
368
  }
361
369
  if (executionIdentity.checkoutId !== input.repository.activeCheckoutId) {
@@ -376,13 +384,12 @@ export async function executeRepositoryCommandViaProcessRuntime(
376
384
  // immutable repository identity first, then execute through the authorized
377
385
  // non-persistent repository executor. Runtime/release durability is not a
378
386
  // command-execution tax.
379
- const canonicalCommand = normalizeRepositoryCommand(input.command);
380
387
  if (decision.route === 'process_direct') {
381
388
  assertExecutionIdentity({
382
389
  controllerHome: input.controllerHome,
383
390
  identity: executionIdentity,
384
391
  cwd,
385
- requestedRepoId: input.repository.repoId,
392
+ requestedRepoId: commandExecutionScopeKey(input.repository),
386
393
  requestedCheckoutId: input.repository.activeCheckoutId,
387
394
  });
388
395
  const directInput = {
@@ -395,8 +402,7 @@ export async function executeRepositoryCommandViaProcessRuntime(
395
402
  allowOpaqueLocalScript: decision.reason === 'lightweight_local_shell_wrapper'
396
403
  || decision.reason === 'lightweight_local_inline_interpreter',
397
404
  };
398
- const readonly = canonicalCommand.kind === 'argv'
399
- && classifyRepositoryCommand(input.command, input.repository.defaultBranch).risk === 'readonly';
405
+ const readonly = classifyRepositoryCommand(input.command, input.repository.defaultBranch).risk === 'readonly';
400
406
  if (!readonly) {
401
407
  const deferLongPreparation = decision.reason === 'ephemeral_local_build_or_test';
402
408
  const interactiveWaitMs = deferLongPreparation
@@ -419,6 +425,7 @@ export async function executeRepositoryCommandViaProcessRuntime(
419
425
  maxOutputBytes: input.maxOutputBytes,
420
426
  workId: input.workId,
421
427
  commandId: input.commandId ?? input.requestId,
428
+ ...(input.principalId ? { principalId: input.principalId } : {}),
422
429
  deferStart: deferLongPreparation,
423
430
  reuseActiveEquivalent: deferLongPreparation,
424
431
  onCompleted: (result) => {
@@ -427,7 +434,7 @@ export async function executeRepositoryCommandViaProcessRuntime(
427
434
  // evidence is unavailable. Finalization must keep failing closed until
428
435
  // a later authoritative repository inspection proves the new HEAD.
429
436
  if (result.evidenceError) return;
430
- settleWorkHandleExpectedHeadAfterRepositoryCommand({
437
+ const settlement = settleWorkHandleExpectedHeadAfterRepositoryCommand({
431
438
  controllerHome: input.controllerHome,
432
439
  repository: input.repository,
433
440
  executionIdentity,
@@ -436,6 +443,12 @@ export async function executeRepositoryCommandViaProcessRuntime(
436
443
  cancelled: result.cancelled,
437
444
  timedOut: result.timedOut,
438
445
  });
446
+ if (!settlement.settled && settlement.reason === 'concurrent_lifecycle_write') {
447
+ result.evidenceError = {
448
+ code: 'WORK_HEAD_SETTLEMENT_UNRESOLVED',
449
+ message: `Work ${input.workId ?? 'unknown'} repository command succeeded, but expectedHead settlement remained contested after bounded retry (${settlement.previousHead ?? 'unknown'} -> ${settlement.currentHead ?? 'unknown'}).`,
450
+ };
451
+ }
439
452
  },
440
453
  });
441
454
  const handle = lightweight.handle;
@@ -526,6 +539,7 @@ export async function executeRepositoryCommandViaProcessRuntime(
526
539
  repoId: executionIdentity.repositoryId,
527
540
  checkoutId: executionIdentity.checkoutId,
528
541
  executionIdentity,
542
+ ...(input.principalId ? { principalId: input.principalId } : {}),
529
543
  workId: input.workId,
530
544
  commandId: input.commandId,
531
545
  command: toProcessCommand(input.command, cwd),
@@ -563,40 +577,78 @@ export async function executeRepositoryCommandViaProcessRuntime(
563
577
  };
564
578
  }
565
579
 
566
- export function getRepositoryCommandProcess(controllerHome: string, repoId: string, processId: string): ProcessHandle | undefined {
567
- return isLightweightProcessId(processId)
568
- ? getLightweightProcessHandle(controllerHome, repoId, processId)
569
- : getProcessHandle(controllerHome, repoId, processId);
580
+ /**
581
+ * Resolve the canonical Process scope of one process handle.
582
+ *
583
+ * Explicit placement stays authoritative and is validated by the lane itself.
584
+ * When the caller omits it, this Runtime's own lightweight memory or the
585
+ * instance-level handle index supplies the recorded scope, so attachment never
586
+ * requires replaying the original placement inputs or scanning repositories.
587
+ */
588
+ function resolveCommandProcessScopeKey(
589
+ controllerHome: string,
590
+ repoId: string | undefined,
591
+ processId: string,
592
+ ): string | undefined {
593
+ const explicit = repoId?.trim();
594
+ if (explicit) return explicit;
595
+ if (isLightweightProcessId(processId)) {
596
+ const inMemory = lightweightProcessScopeKey(processId);
597
+ if (inMemory) return inMemory;
598
+ }
599
+ return processScopeKeyForHandle(controllerHome, processId);
570
600
  }
571
601
 
572
- export function waitRepositoryCommandProcess(
602
+ export function getRepositoryCommandProcess(
573
603
  controllerHome: string,
574
- repoId: string,
604
+ repoId: string | undefined,
605
+ processId: string,
606
+ ): ProcessHandle | undefined {
607
+ const scopeKey = resolveCommandProcessScopeKey(controllerHome, repoId, processId);
608
+ if (!scopeKey) return undefined;
609
+ if (!isLightweightProcessId(processId)) {
610
+ return getProcessHandle(controllerHome, scopeKey, processId);
611
+ }
612
+ return getLightweightProcessHandle(controllerHome, scopeKey, processId);
613
+ }
614
+
615
+ export async function waitRepositoryCommandProcess(
616
+ controllerHome: string,
617
+ repoId: string | undefined,
575
618
  processId: string,
576
619
  options?: Parameters<typeof waitForProcess>[3],
577
620
  ): Promise<ProcessHandle> {
578
- return isLightweightProcessId(processId)
579
- ? waitForLightweightProcess(controllerHome, repoId, processId, options)
580
- : waitForProcess(controllerHome, repoId, processId, options);
621
+ const scopeKey = resolveCommandProcessScopeKey(controllerHome, repoId, processId);
622
+ if (!scopeKey) throw new Error(`PROCESS_NOT_FOUND: ${processId}`);
623
+ if (!isLightweightProcessId(processId)) {
624
+ return waitForProcess(controllerHome, scopeKey, processId, options);
625
+ }
626
+ return waitForLightweightProcess(controllerHome, scopeKey, processId, options);
581
627
  }
582
628
 
583
- export function cancelRepositoryCommandProcess(
629
+ export async function cancelRepositoryCommandProcess(
584
630
  controllerHome: string,
585
- repoId: string,
631
+ repoId: string | undefined,
586
632
  processId: string,
587
633
  ): Promise<ProcessHandle> {
588
- return isLightweightProcessId(processId)
589
- ? cancelLightweightProcess(controllerHome, repoId, processId)
590
- : cancelProcess(controllerHome, repoId, processId);
634
+ const scopeKey = resolveCommandProcessScopeKey(controllerHome, repoId, processId);
635
+ if (!scopeKey) throw new Error(`PROCESS_NOT_FOUND: ${processId}`);
636
+ if (!isLightweightProcessId(processId)) {
637
+ return cancelProcess(controllerHome, scopeKey, processId);
638
+ }
639
+ return cancelLightweightProcess(controllerHome, scopeKey, processId);
591
640
  }
592
641
 
593
642
  export function readRepositoryCommandProcessLogs(
594
643
  controllerHome: string,
595
- repoId: string,
644
+ repoId: string | undefined,
596
645
  processId: string,
597
646
  maxBytes?: number,
598
647
  ) {
599
- return isLightweightProcessId(processId)
600
- ? readLightweightProcessLogs(controllerHome, repoId, processId, maxBytes)
601
- : readProcessLogs(controllerHome, repoId, processId, maxBytes);
648
+ const scopeKey = resolveCommandProcessScopeKey(controllerHome, repoId, processId);
649
+ if (!scopeKey) return undefined;
650
+ if (!isLightweightProcessId(processId)) {
651
+ return readProcessLogs(controllerHome, scopeKey, processId, maxBytes);
652
+ }
653
+ return readLightweightProcessLogs(controllerHome, scopeKey, processId, maxBytes);
602
654
  }
@@ -9,8 +9,9 @@
9
9
  import { existsSync, readFileSync, readdirSync, unlinkSync, statSync } from 'fs';
10
10
  import { join } from 'path';
11
11
  import { ensureRepositoryControllerLayout, repositoryControllerRoot } from '../../../cli/repositories/controller-home';
12
+ import { isRepositoryProcessScopeKey, processScopeRoot } from './process-scope';
12
13
  import { getProcessRecord, listActiveProcessIds } from './store';
13
- import { reconcileStaleManagedProcessForMaintenance } from './runtime';
14
+ import { reconcileStaleManagedProcessForMaintenance, releaseProcessLeasesOnce } from './runtime';
14
15
  import { isManagedProcessActive, type ProcessRuntimeStatus } from './types';
15
16
  import { assertRuntimeMayWrite } from '../../root/write-fence';
16
17
  import { isProcessAlive } from '../../shared/process-tree';
@@ -52,7 +53,12 @@ export interface ProcessGcResult {
52
53
  }
53
54
 
54
55
  function processesDir(controllerHome: string, repoId: string): string {
55
- return join(ensureRepositoryControllerLayout(controllerHome, repoId), 'processes');
56
+ // Repository scopes keep their per-repository layout; instance and workspace
57
+ // scopes own sibling partitions so their process records are still collected.
58
+ const root = isRepositoryProcessScopeKey(repoId)
59
+ ? ensureRepositoryControllerLayout(controllerHome, repoId)
60
+ : processScopeRoot(controllerHome, repoId);
61
+ return join(root, 'processes');
56
62
  }
57
63
 
58
64
  function logDir(controllerHome: string, repoId: string): string {
@@ -196,6 +202,13 @@ export function gcTerminalProcesses(options: ProcessGcOptions): ProcessGcResult
196
202
  }
197
203
  }
198
204
  if (!TERMINAL.has(metadata.status)) continue;
205
+ // Terminal evidence and lease cleanup are separate durable phases. A
206
+ // crash/fence between them must not leave a workspace lease immortal just
207
+ // because the terminal record is still inside the retention window.
208
+ const terminalRecord = getProcessRecord(options.controllerHome, options.repoId, processId);
209
+ if (terminalRecord?.terminalWritten === true && terminalRecord.leasesReleased !== true) {
210
+ releaseProcessLeasesOnce(options.controllerHome, options.repoId, processId);
211
+ }
199
212
  // Do not delete terminal evidence that has never been read when maxAge is not exceeded
200
213
  // unless we are strictly over maxTerminalRecords budget (handled by sort below).
201
214
  const finished = Date.parse(metadata.finishedAt ?? metadata.updatedAt ?? '');
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Instance-level Process handle index.
3
+ *
4
+ * Process attachment (get/wait/logs/cancel) resolves the concrete execution
5
+ * target from the returned handle identity instead of replaying the original
6
+ * placement inputs or scanning every repository partition. The index lives in
7
+ * Controller Home, so it is a ForgeInstance-level locator: repository/checkout
8
+ * placement is target metadata, never the address space of the process itself.
9
+ *
10
+ * This is a rebuildable locator projection. The Process Runtime record and its
11
+ * exit receipt remain the only outcome evidence; a missing or stale index entry
12
+ * degrades attachment convenience and never becomes a capability gate.
13
+ */
14
+
15
+ import { readForgeInstanceIdentity } from '../../../../packages/kernel/identity/api/index';
16
+ import { mutateControlPlaneRecord, readControlPlaneRecord } from '../../control-plane/persistence/sqlite-store';
17
+
18
+ export const PROCESS_HANDLE_INDEX_NAMESPACE = 'process_handle_index';
19
+ const PROCESS_HANDLE_INDEX_SCOPE = 'instance';
20
+ const PROCESS_HANDLE_INDEX_SCHEMA_VERSION = 1;
21
+
22
+ export type ProcessExecutionTargetScope = 'forge_instance' | 'repository' | 'workspace';
23
+
24
+ /** Typed execution target for one process handle. Repository placement is optional context. */
25
+ export interface ProcessExecutionTarget {
26
+ schemaVersion: 1;
27
+ scope: ProcessExecutionTargetScope;
28
+ forgeInstanceId?: string;
29
+ repositoryId?: string;
30
+ /** Workspace scope id when the target is an arbitrary workspace without repository semantics. */
31
+ workspaceId?: string;
32
+ checkoutId?: string;
33
+ }
34
+
35
+ export interface ProcessHandleIndexEntry {
36
+ schemaVersion: 1;
37
+ processId: string;
38
+ lane: 'lightweight' | 'managed';
39
+ target: ProcessExecutionTarget;
40
+ /** Authenticated principal that owns the handle; opaque ids never authorize by themselves. */
41
+ principalId?: string;
42
+ workId?: string;
43
+ commandId?: string;
44
+ recordedAt: string;
45
+ updatedAt: string;
46
+ }
47
+
48
+ function boundedId(value: string | undefined): string | undefined {
49
+ const normalized = value?.trim();
50
+ return normalized ? normalized.slice(0, 512) : undefined;
51
+ }
52
+
53
+ export function forgeInstanceIdFor(controllerHome: string): string | undefined {
54
+ return readForgeInstanceIdentity(controllerHome)?.instanceId;
55
+ }
56
+
57
+ export function forgeInstanceExecutionTarget(controllerHome: string): ProcessExecutionTarget {
58
+ const forgeInstanceId = forgeInstanceIdFor(controllerHome);
59
+ return { schemaVersion: 1, scope: 'forge_instance', ...(forgeInstanceId ? { forgeInstanceId } : {}) };
60
+ }
61
+
62
+ export function repositoryExecutionTarget(
63
+ controllerHome: string,
64
+ repositoryId: string,
65
+ checkoutId?: string,
66
+ ): ProcessExecutionTarget {
67
+ const forgeInstanceId = forgeInstanceIdFor(controllerHome);
68
+ const repository = boundedId(repositoryId);
69
+ if (!repository) throw new Error('PROCESS_EXECUTION_TARGET_REPOSITORY_REQUIRED');
70
+ const checkout = boundedId(checkoutId);
71
+ return {
72
+ schemaVersion: 1,
73
+ scope: 'repository',
74
+ ...(forgeInstanceId ? { forgeInstanceId } : {}),
75
+ repositoryId: repository,
76
+ ...(checkout ? { checkoutId: checkout } : {}),
77
+ };
78
+ }
79
+
80
+ /** Target for an arbitrary workspace: no repository identity is created or implied. */
81
+ export function workspaceExecutionTarget(controllerHome: string, workspaceId: string): ProcessExecutionTarget {
82
+ const workspace = boundedId(workspaceId);
83
+ if (!workspace) throw new Error('PROCESS_EXECUTION_TARGET_WORKSPACE_REQUIRED');
84
+ const forgeInstanceId = forgeInstanceIdFor(controllerHome);
85
+ return {
86
+ schemaVersion: 1,
87
+ scope: 'workspace',
88
+ ...(forgeInstanceId ? { forgeInstanceId } : {}),
89
+ workspaceId: workspace,
90
+ };
91
+ }
92
+
93
+ export function recordProcessHandleIndexEntry(
94
+ controllerHome: string,
95
+ input: Omit<ProcessHandleIndexEntry, 'schemaVersion' | 'recordedAt' | 'updatedAt'> & { now?: string },
96
+ ): ProcessHandleIndexEntry | undefined {
97
+ const processId = boundedId(input.processId);
98
+ if (!processId) return undefined;
99
+ const now = input.now ?? new Date().toISOString();
100
+ const principalId = boundedId(input.principalId);
101
+ const workId = boundedId(input.workId);
102
+ const commandId = boundedId(input.commandId);
103
+ try {
104
+ const record = mutateControlPlaneRecord<ProcessHandleIndexEntry>(controllerHome, {
105
+ namespace: PROCESS_HANDLE_INDEX_NAMESPACE,
106
+ scope: PROCESS_HANDLE_INDEX_SCOPE,
107
+ key: processId,
108
+ schemaVersion: PROCESS_HANDLE_INDEX_SCHEMA_VERSION,
109
+ action: 'process_handle_index_record',
110
+ mutate: (current) => ({
111
+ schemaVersion: PROCESS_HANDLE_INDEX_SCHEMA_VERSION,
112
+ processId,
113
+ lane: input.lane,
114
+ target: input.target,
115
+ ...(principalId ? { principalId } : {}),
116
+ ...(current?.value.principalId && !principalId ? { principalId: current.value.principalId } : {}),
117
+ ...(workId ? { workId } : {}),
118
+ ...(commandId ? { commandId } : {}),
119
+ recordedAt: current?.value.recordedAt ?? now,
120
+ updatedAt: now,
121
+ }),
122
+ });
123
+ return record.value;
124
+ } catch {
125
+ // A locator projection must never block an already-authorized process.
126
+ return undefined;
127
+ }
128
+ }
129
+
130
+ export function readProcessHandleIndexEntry(
131
+ controllerHome: string,
132
+ processId: string,
133
+ ): ProcessHandleIndexEntry | undefined {
134
+ const key = boundedId(processId);
135
+ if (!key) return undefined;
136
+ try {
137
+ const record = readControlPlaneRecord<ProcessHandleIndexEntry>(
138
+ controllerHome,
139
+ PROCESS_HANDLE_INDEX_NAMESPACE,
140
+ PROCESS_HANDLE_INDEX_SCOPE,
141
+ key,
142
+ );
143
+ const value = record?.value;
144
+ if (!value || value.schemaVersion !== PROCESS_HANDLE_INDEX_SCHEMA_VERSION || value.processId !== key) return undefined;
145
+ if (!value.target || value.target.schemaVersion !== 1) return undefined;
146
+ return value;
147
+ } catch {
148
+ return undefined;
149
+ }
150
+ }
151
+
152
+ /** Resolve the concrete execution target recorded for one process handle. */
153
+ export function resolveProcessExecutionTarget(
154
+ controllerHome: string,
155
+ processId: string,
156
+ ): ProcessExecutionTarget | undefined {
157
+ return readProcessHandleIndexEntry(controllerHome, processId)?.target;
158
+ }
159
+
160
+ /**
161
+ * Principal that owns one process handle, when recorded. Opaque handle ids
162
+ * locate a record; they never authorize attachment on their own.
163
+ */
164
+ export function processHandlePrincipalId(controllerHome: string, processId: string): string | undefined {
165
+ return readProcessHandleIndexEntry(controllerHome, processId)?.principalId;
166
+ }
167
+
168
+ /** Compatibility narrowing: the repository placement recorded for a process, when it has one. */
169
+ export function resolveProcessRepositoryTarget(
170
+ controllerHome: string,
171
+ processId: string,
172
+ ): { repositoryId: string; checkoutId?: string } | undefined {
173
+ const target = resolveProcessExecutionTarget(controllerHome, processId);
174
+ if (!target?.repositoryId) return undefined;
175
+ return { repositoryId: target.repositoryId, ...(target.checkoutId ? { checkoutId: target.checkoutId } : {}) };
176
+ }