@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,7 +1,10 @@
1
- import type { WorkContract, WorkContractStore, WorkContractStatus } from '../domain/types';
1
+ import type { SemanticWorkState, WorkContract, WorkContractStore } from '../domain/types';
2
2
 
3
3
  export interface WorkContractStoreLocation {
4
4
  controllerHome?: string;
5
+ /** Canonical storage scope. Semantic Work uses the portable semantic scope; repository Work may omit this and use repoId. */
6
+ scopeKey?: string;
7
+ /** Legacy/repository execution storage scope and optional placement context. */
5
8
  repoId?: string;
6
9
  root?: string;
7
10
  }
@@ -14,5 +17,5 @@ export interface WorkContractStoreOptions extends WorkContractStoreLocation {
14
17
  export interface WorkContractPersistencePort {
15
18
  read(options: WorkContractStoreOptions): WorkContractStore;
16
19
  get(options: WorkContractStoreOptions, workId: string): WorkContract | undefined;
17
- list(options: WorkContractStoreOptions & { status?: WorkContractStatus | 'active' | 'all'; limit?: number }): WorkContract[];
20
+ list(options: WorkContractStoreOptions & { state?: SemanticWorkState | 'active' | 'all'; limit?: number }): WorkContract[];
18
21
  }
@@ -4,7 +4,8 @@ export const MAX_BROWSER_SESSION_LIST_LIMIT = 200;
4
4
  /** State-free Browser execution scope. Durable interaction identity belongs to Computer SurfaceTarget authority. */
5
5
  export interface BrowserSessionExecutionContext {
6
6
  controllerHome: string;
7
- repoId: string;
7
+ /** Optional repository visibility/migration context; never Browser session authority. */
8
+ repoId?: string;
8
9
  }
9
10
 
10
11
  /** @deprecated Compatibility alias for frozen callers; this is context, not an authority capability. */
@@ -0,0 +1,24 @@
1
+ const CHATGPT_HOSTS = new Set(['chatgpt.com', 'www.chatgpt.com', 'chat.openai.com']);
2
+ const MAX_CONVERSATION_ID_CHARS = 256;
3
+
4
+ export interface CanonicalChatgptConversationIdentity {
5
+ conversationUrl: string;
6
+ conversationId: string;
7
+ }
8
+
9
+ export function parseCanonicalChatgptConversationIdentity(value: string): CanonicalChatgptConversationIdentity {
10
+ let url: URL;
11
+ try { url = new URL(value); } catch { throw new Error('CHATGPT_CONVERSATION_URL_INVALID'); }
12
+ if (url.protocol !== 'https:' || !CHATGPT_HOSTS.has(url.hostname)) throw new Error('CHATGPT_CONVERSATION_URL_INVALID');
13
+ const parts = url.pathname.split('/').filter(Boolean);
14
+ const marker = parts.lastIndexOf('c');
15
+ if (marker < 0 || marker + 2 !== parts.length) throw new Error('CHATGPT_CONVERSATION_ID_MISSING');
16
+ const conversationId = parts[marker + 1]?.trim() ?? '';
17
+ if (!conversationId) throw new Error('CHATGPT_CONVERSATION_ID_MISSING');
18
+ if (conversationId.length > MAX_CONVERSATION_ID_CHARS) throw new Error('CHATGPT_CONVERSATION_ID_INVALID');
19
+ url.protocol = 'https:';
20
+ url.hostname = 'chatgpt.com';
21
+ url.search = '';
22
+ url.hash = '';
23
+ return { conversationUrl: url.toString(), conversationId };
24
+ }
@@ -0,0 +1,143 @@
1
+ import type { ComputerSurfaceProviderBinding } from './target-authority';
2
+
3
+ export interface ComputerChatgptConversationIdentity {
4
+ namespace: 'chatgpt.conversation';
5
+ conversationId: string;
6
+ canonicalUrl: string;
7
+ }
8
+
9
+ export interface ComputerChatgptBootstrapIdentity {
10
+ namespace: 'chatgpt.bootstrap';
11
+ bootstrapKey: string;
12
+ projectUrl: string;
13
+ }
14
+
15
+ export type ComputerChatgptTargetIdentity = ComputerChatgptConversationIdentity | ComputerChatgptBootstrapIdentity;
16
+
17
+ export interface ComputerChatgptConversationObservation {
18
+ url: string;
19
+ title: string;
20
+ latestUserText: string;
21
+ latestAssistantResponse: string;
22
+ userMessages?: string[];
23
+ assistantMessages?: string[];
24
+ composerText?: string;
25
+ providerActivityText: string;
26
+ providerFailureText: string;
27
+ pageText?: string;
28
+ latestTurnRole?: 'user' | 'assistant';
29
+ isGenerating: boolean;
30
+ }
31
+
32
+ export interface ComputerChatgptConversationObservationOptions {
33
+ includeUserHistory?: boolean;
34
+ includePageText?: boolean;
35
+ }
36
+
37
+ /**
38
+ * Opaque exact-conversation attachment. The targetId is durable Computer
39
+ * identity; provider ids and tab/window handles remain inside the Computer
40
+ * implementation and can be replaced without changing Supervisor authority.
41
+ */
42
+ export interface ComputerChatgptConversationTarget {
43
+ targetId: string;
44
+ identity: ComputerChatgptTargetIdentity;
45
+ observe(options?: ComputerChatgptConversationObservationOptions): Promise<ComputerChatgptConversationObservation>;
46
+ /** UI-only preparation. Must never click Send or create a provider turn. */
47
+ prepare(prompt: string, options?: { mode?: 'send' | 'resume' | 'recover'; reasoning?: 'medium' | 'high' | 'xhigh' }): Promise<{ ready: true } | { ready: false; reasonCode: string }>;
48
+ dispatch(
49
+ prompt: string,
50
+ options?: { mode?: 'send' | 'resume' | 'recover'; reasoning?: 'medium' | 'high' | 'xhigh' },
51
+ ): Promise<
52
+ | { mutation: 'not_attempted'; reasonCode: string }
53
+ | { mutation: 'attempted'; confirmed?: boolean; reasoningVerified?: 'medium' | 'high' | 'xhigh' }
54
+ >;
55
+ }
56
+
57
+ export type ComputerChatgptTargetFailure = {
58
+ code: string;
59
+ retryable: boolean;
60
+ /** Failover is legal only while provider mutation is mechanically impossible. */
61
+ phase: 'pre_mutation';
62
+ /** False when provider resource recovery is itself outcome-unknown. */
63
+ failoverSafe?: boolean;
64
+ humanAction?: 'login' | 'grant_permission';
65
+ };
66
+
67
+ export type ComputerChatgptTargetResult =
68
+ | { state: 'ready'; target: ComputerChatgptConversationTarget; observation?: ComputerChatgptConversationObservation }
69
+ | { state: 'unavailable'; failure: ComputerChatgptTargetFailure };
70
+
71
+ export interface ComputerObservedChatgptConversation {
72
+ conversationId: string;
73
+ canonicalUrl: string;
74
+ title?: string;
75
+ projectTitle?: string;
76
+ projectUrl?: string;
77
+ isCurrent?: boolean;
78
+ }
79
+
80
+ export interface ComputerChatgptConversationInventory {
81
+ conversations: ComputerObservedChatgptConversation[];
82
+ complete: boolean;
83
+ unavailableProviders: string[];
84
+ }
85
+
86
+ /**
87
+ * Browser/Computer-owned target boundary consumed by Workflow Supervisor.
88
+ * Implementations own discovery, exact target recovery, provider binding and
89
+ * transport replacement. They never decide effect admission or effect outcome.
90
+ */
91
+ export type ComputerChatgptExtensionCommand =
92
+ | { commandId: string; kind: 'ensure'; identity: ComputerChatgptTargetIdentity; providerBinding?: ComputerSurfaceProviderBinding }
93
+ | { commandId: string; kind: 'observe'; identity: ComputerChatgptTargetIdentity; providerBinding?: ComputerSurfaceProviderBinding; options?: ComputerChatgptConversationObservationOptions }
94
+ | { commandId: string; kind: 'dispatch' | 'prepare'; identity: ComputerChatgptTargetIdentity; providerBinding?: ComputerSurfaceProviderBinding; prompt: string; mode?: 'send' | 'resume' | 'recover'; reasoning?: 'medium' | 'high' | 'xhigh' }
95
+ | { commandId: string; kind: 'find_marker'; marker: string; bootstrapKey?: string }
96
+ | { commandId: string; kind: 'close'; identity: ComputerChatgptTargetIdentity; providerBinding?: ComputerSurfaceProviderBinding };
97
+ export type ComputerChatgptExtensionCommandInput = ComputerChatgptExtensionCommand extends infer Command
98
+ ? Command extends { commandId: string }
99
+ ? Omit<Command, 'commandId'>
100
+ : never
101
+ : never;
102
+
103
+
104
+ export type ComputerChatgptExtensionCommandResult =
105
+ | { kind: 'ensured'; providerBinding?: ComputerSurfaceProviderBinding; observation?: ComputerChatgptConversationObservation }
106
+ | { kind: 'observation'; providerBinding?: ComputerSurfaceProviderBinding; observation: ComputerChatgptConversationObservation }
107
+ | { kind: 'prepared'; ready: true }
108
+ | { kind: 'prepared'; ready: false; reasonCode: string }
109
+ | { kind: 'dispatch'; mutation: 'not_attempted'; reasonCode: string }
110
+ | { kind: 'dispatch'; mutation: 'attempted'; confirmed?: boolean; reasoningVerified?: 'medium' | 'high' | 'xhigh'; observation?: ComputerChatgptConversationObservation }
111
+ | { kind: 'marker_matches'; matches: Array<{ identity: ComputerChatgptConversationIdentity; providerBinding?: ComputerSurfaceProviderBinding; observation: ComputerChatgptConversationObservation }> }
112
+ | { kind: 'closed' }
113
+ | { kind: 'failed'; code: string; retryable?: boolean; failoverSafe?: boolean; humanAction?: 'login' | 'grant_permission' };
114
+
115
+ export interface ComputerChatgptExtensionHeartbeat {
116
+ providerId: string;
117
+ /** Ephemeral browser/profile provider runtime identity; mechanical binding only. */
118
+ providerInstanceId: string;
119
+ observedAt: string;
120
+ conversations: Array<ComputerObservedChatgptConversation & { providerBinding?: ComputerSurfaceProviderBinding }>;
121
+ }
122
+
123
+ export interface ComputerChatgptExtensionBrokerRpc {
124
+ heartbeat(input: ComputerChatgptExtensionHeartbeat): void;
125
+ claim(providerInstanceId: string): ComputerChatgptExtensionCommand | undefined;
126
+ complete(providerInstanceId: string, commandId: string, result: ComputerChatgptExtensionCommandResult): boolean;
127
+ }
128
+
129
+ export interface ComputerChatgptConversationTargetPort {
130
+ inventory(): Promise<ComputerChatgptConversationInventory>;
131
+ ensureExact(identity: ComputerChatgptConversationIdentity): Promise<ComputerChatgptTargetResult>;
132
+ openBootstrap(projectUrl: string, bootstrapKey: string): Promise<ComputerChatgptTargetResult>;
133
+ findBySubmittedMarker(
134
+ marker: string,
135
+ bootstrapKey?: string,
136
+ betweenObservations?: () => Promise<void>,
137
+ ): Promise<ComputerChatgptTargetResult[]>;
138
+ promoteBootstrap(targetId: string, identity: ComputerChatgptConversationIdentity): Promise<ComputerChatgptTargetResult>;
139
+ /** Mechanical cleanup of provider-owned attachments; semantic target identity remains durable. */
140
+ cleanup(activeResourceKeys: readonly string[]): Promise<void>;
141
+ release(targetId: string): Promise<void>;
142
+ close(): Promise<void>;
143
+ }
@@ -4,3 +4,5 @@ export * from './provider-error';
4
4
  export * from './provider-registration';
5
5
  export * from './target-authority';
6
6
  export * from './target-persistence';
7
+ export * from './conversation-target';
8
+ export * from './chatgpt-identity';
@@ -8,8 +8,14 @@ export interface ComputerProviderTargetBinding {
8
8
  providerId: string;
9
9
  providerSessionId: string;
10
10
  observedAt: string;
11
+ /** Rebuildable exact native process observation for cross-target lifecycle fencing. */
12
+ processId?: number;
11
13
  }
12
14
 
15
+ export type ComputerApplicationLaunchProvenance =
16
+ | { kind: 'preexisting' }
17
+ | { kind: 'provider_launched'; processId: number };
18
+
13
19
  export type ComputerSurfaceType = 'browser-tab' | 'browser-page';
14
20
  export type ComputerSurfaceOwnership = 'plugin_owned' | 'user_owned' | 'provider_owned';
15
21
  export type ComputerSurfaceVisibility = 'repositories' | 'controller';
@@ -18,10 +24,19 @@ export type ComputerSurfaceVisibility = 'repositories' | 'controller';
18
24
  * Durable semantic description of a Computer surface. Mutable URL/title and
19
25
  * provider-specific tab/window handles are deliberately excluded.
20
26
  */
27
+ export interface ComputerSurfaceResourceIdentity {
28
+ /** Stable semantic namespace, for example chatgpt.conversation. */
29
+ namespace: string;
30
+ /** Provider-independent durable resource key inside the namespace. */
31
+ key: string;
32
+ }
33
+
21
34
  export interface ComputerSurfaceStableIdentity {
22
35
  surfaceType: ComputerSurfaceType;
23
36
  ownership: ComputerSurfaceOwnership;
24
37
  application?: ComputerApplicationStableIdentity;
38
+ /** Durable semantic identity. Provider tab/window/session ids never belong here. */
39
+ resource?: ComputerSurfaceResourceIdentity;
25
40
  }
26
41
 
27
42
  /**
@@ -52,6 +67,8 @@ export interface ComputerApplicationTarget {
52
67
  targetId: string;
53
68
  kind: 'application';
54
69
  stableIdentity: ComputerApplicationStableIdentity;
70
+ /** Durable launch fact. Missing means a legacy provider supplied no trustworthy provenance. */
71
+ launchProvenance?: ComputerApplicationLaunchProvenance;
55
72
  providerBinding?: ComputerProviderTargetBinding;
56
73
  createdAt: string;
57
74
  updatedAt: string;
@@ -93,6 +110,8 @@ export interface ComputerApplicationTargetLease {
93
110
  export interface ComputerSurfaceTargetLease {
94
111
  current(): ComputerSurfaceTarget;
95
112
  bind(binding: ComputerSurfaceProviderBinding): ComputerSurfaceTarget;
113
+ /** Provider attachment is rebuildable and may be cleared without changing target identity. */
114
+ clearBinding(): ComputerSurfaceTarget;
96
115
  mergeCompatibility(input: { compatibilityAliases?: string[]; repositoryIds?: string[] }): ComputerSurfaceTarget;
97
116
  putCompatibility(record: ComputerSurfaceCompatibilityRecord): ComputerSurfaceTarget;
98
117
  tombstone(): ComputerSurfaceTarget;
@@ -146,10 +165,15 @@ export interface ComputerInteractionTargetCleanupReport {
146
165
  export interface ComputerInteractionTargetAuthorityPort {
147
166
  create(
148
167
  controllerHome: string,
149
- input: { stableIdentity: ComputerApplicationStableIdentity; providerBinding?: ComputerProviderTargetBinding },
168
+ input: {
169
+ stableIdentity: ComputerApplicationStableIdentity;
170
+ launchProvenance?: ComputerApplicationLaunchProvenance;
171
+ providerBinding?: ComputerProviderTargetBinding;
172
+ },
150
173
  ): ComputerApplicationTarget;
151
174
  get(controllerHome: string, targetId: string): ComputerApplicationTarget | undefined;
152
175
  require(controllerHome: string, targetId: string): ComputerApplicationTarget;
176
+ listAllApplications(controllerHome: string): ComputerApplicationTarget[];
153
177
  withLease<T>(
154
178
  controllerHome: string,
155
179
  targetId: string,
@@ -171,6 +195,7 @@ export interface ComputerInteractionTargetAuthorityPort {
171
195
  getSurface(controllerHome: string, targetId: string): ComputerSurfaceTarget | undefined;
172
196
  requireSurface(controllerHome: string, targetId: string): ComputerSurfaceTarget;
173
197
  findSurfaceByAlias(controllerHome: string, alias: string, repoId?: string): ComputerSurfaceTarget | undefined;
198
+ findSurfaceByStableIdentity(controllerHome: string, identity: ComputerSurfaceStableIdentity, repoId?: string): ComputerSurfaceTarget | undefined;
174
199
  findSurfaceByProviderBinding(controllerHome: string, binding: ComputerSurfaceProviderBinding): ComputerSurfaceTarget | undefined;
175
200
  listSurfaces(controllerHome: string, options?: { repoId?: string; limit?: number }): ComputerSurfaceTarget[];
176
201
  listAllSurfaces(controllerHome: string, options?: { repoId?: string }): ComputerSurfaceTarget[];
@@ -5,7 +5,14 @@ const DEFAULT_TIMEOUT_MS = 30_000;
5
5
  const DEFAULT_HEALTH_TIMEOUT_MS = 2_000;
6
6
  const DEFAULT_MAX_REQUEST_BYTES = 1_048_576;
7
7
  const DEFAULT_MAX_RESPONSE_BYTES = 1_048_576;
8
- const MAX_TIMEOUT_MS = 120_000;
8
+ export const MAX_PLUGIN_ACTION_TIMEOUT_MS = 10 * 60_000;
9
+ /**
10
+ * How long an already-dispatched request keeps its connection open after the
11
+ * caller stopped waiting. Destroying that socket makes the provider's own write
12
+ * fail (SIGPIPE / EPIPE) and can terminate a long-running provider service that
13
+ * is still completing bounded work. Draining absorbs the late response instead.
14
+ */
15
+ const UNANSWERED_DRAIN_TIMEOUT_MS = 15_000;
9
16
  export const EXTERNAL_RPC_METHOD_PATTERN = /^[a-z][a-z0-9_]{0,127}$/;
10
17
 
11
18
  export type ExternalUnixJsonlMethod = string;
@@ -98,6 +105,61 @@ function transportError(
98
105
  return new ExternalUnixJsonlTransportError(code, message, options);
99
106
  }
100
107
 
108
+ /**
109
+ * Absorb a response that nobody is waiting for any more.
110
+ *
111
+ * A client that abandons a dispatched request must not tear the connection down
112
+ * underneath the provider: an in-flight provider write to a closed peer raises
113
+ * SIGPIPE and kills single-threaded provider services, which then restart into
114
+ * the same request forever. Keeping the connection open until the provider's
115
+ * own response arrives preserves the provider lifecycle while discarding the
116
+ * now-meaningless payload.
117
+ */
118
+ function drainUnansweredResponse(options: {
119
+ socket: Socket;
120
+ maxResponseBytes: number;
121
+ onFinished: (socket: Socket) => void;
122
+ }): void {
123
+ const { socket, maxResponseBytes, onFinished } = options;
124
+ if (socket.destroyed) {
125
+ onFinished(socket);
126
+ return;
127
+ }
128
+ let buffer = Buffer.alloc(0);
129
+ let settled = false;
130
+ const settle = (destroy: boolean): void => {
131
+ if (settled) return;
132
+ settled = true;
133
+ clearTimeout(timer);
134
+ socket.removeListener('data', onData);
135
+ socket.removeListener('end', onEnd);
136
+ socket.removeListener('error', onEnd);
137
+ socket.removeListener('close', onEnd);
138
+ if (!socket.destroyed) {
139
+ // The provider finished writing its late response: a graceful half-close
140
+ // is enough, and it never turns into a provider-side write failure.
141
+ if (destroy) socket.destroy();
142
+ else socket.end();
143
+ }
144
+ onFinished(socket);
145
+ };
146
+ const onData = (chunk: Buffer): void => {
147
+ if (buffer.length + chunk.length > maxResponseBytes) {
148
+ settle(true);
149
+ return;
150
+ }
151
+ buffer = Buffer.concat([buffer, chunk]);
152
+ if (buffer.indexOf(0x0A) >= 0) settle(false);
153
+ };
154
+ const onEnd = (): void => settle(true);
155
+ const timer = setTimeout(() => settle(true), UNANSWERED_DRAIN_TIMEOUT_MS);
156
+ timer.unref?.();
157
+ socket.on('data', onData);
158
+ socket.once('end', onEnd);
159
+ socket.once('error', onEnd);
160
+ socket.once('close', onEnd);
161
+ }
162
+
101
163
  function normalizeTransportError(error: unknown): ExternalUnixJsonlTransportError {
102
164
  return error instanceof ExternalUnixJsonlTransportError
103
165
  ? error
@@ -152,7 +214,7 @@ export function normalizeExternalUnixJsonlCall(
152
214
  const params = options.params ?? {};
153
215
  const maxRequestBytes = boundedInteger(options.maxRequestBytes, DEFAULT_MAX_REQUEST_BYTES, 1_024, 4 * DEFAULT_MAX_REQUEST_BYTES);
154
216
  const maxResponseBytes = boundedInteger(options.maxResponseBytes, DEFAULT_MAX_RESPONSE_BYTES, 1_024, 4 * DEFAULT_MAX_RESPONSE_BYTES);
155
- const timeoutMs = boundedInteger(options.timeoutMs, health ? DEFAULT_HEALTH_TIMEOUT_MS : DEFAULT_TIMEOUT_MS, 100, MAX_TIMEOUT_MS);
217
+ const timeoutMs = boundedInteger(options.timeoutMs, health ? DEFAULT_HEALTH_TIMEOUT_MS : DEFAULT_TIMEOUT_MS, 100, MAX_PLUGIN_ACTION_TIMEOUT_MS);
156
218
  const envelope = `${JSON.stringify({ id: options.requestId, method, params })}\n`;
157
219
  if (Buffer.byteLength(envelope, 'utf8') > maxRequestBytes) {
158
220
  throw transportError('EXTERNAL_PLUGIN_REQUEST_TOO_LARGE', 'External provider request exceeded the bounded input limit.', { retryable: false });
@@ -200,6 +262,9 @@ export class ExternalUnixJsonlChannel {
200
262
  private queue: Promise<void> = Promise.resolve();
201
263
  private generationValue = 0;
202
264
  private disposed = false;
265
+ private outstandingDispatched = 0;
266
+ private outstandingMaxResponseBytes = DEFAULT_MAX_RESPONSE_BYTES;
267
+ private readonly draining = new Set<Socket>();
203
268
 
204
269
  constructor(readonly socketPath: string) {
205
270
  validateSocketPath(socketPath);
@@ -235,6 +300,10 @@ export class ExternalUnixJsonlChannel {
235
300
 
236
301
  close(): void {
237
302
  this.disposed = true;
303
+ if (this.outstandingDispatched > 0 && this.socket) {
304
+ this.retireForDrain(this.socket, this.outstandingMaxResponseBytes);
305
+ return;
306
+ }
238
307
  this.resetSocket();
239
308
  }
240
309
 
@@ -245,6 +314,24 @@ export class ExternalUnixJsonlChannel {
245
314
  this.buffer = Buffer.alloc(0);
246
315
  }
247
316
 
317
+ /**
318
+ * Retire a connection whose request was abandoned by the caller. The socket
319
+ * leaves service immediately, but stays open until the provider's own
320
+ * response is absorbed so the provider is never killed by its late write.
321
+ */
322
+ private retireForDrain(socket: Socket, maxResponseBytes: number): void {
323
+ if (this.socket === socket) this.socket = undefined;
324
+ this.connecting = undefined;
325
+ this.buffer = Buffer.alloc(0);
326
+ if (socket.destroyed) return;
327
+ this.draining.add(socket);
328
+ drainUnansweredResponse({
329
+ socket,
330
+ maxResponseBytes,
331
+ onFinished: (finished) => { this.draining.delete(finished); },
332
+ });
333
+ }
334
+
248
335
  private async ensureConnected(): Promise<void> {
249
336
  if (this.connected) return;
250
337
  if (this.connecting) return await this.connecting;
@@ -299,7 +386,7 @@ export class ExternalUnixJsonlChannel {
299
386
  let settled = false;
300
387
  let dispatched = false;
301
388
  let socket: Socket | undefined;
302
- const finish = (callback: () => void, reset = false): void => {
389
+ const finish = (callback: () => void, disposition: 'keep' | 'reset' | 'drain' = 'keep'): void => {
303
390
  if (settled) return;
304
391
  settled = true;
305
392
  if (timer) clearTimeout(timer);
@@ -307,15 +394,20 @@ export class ExternalUnixJsonlChannel {
307
394
  socket?.removeListener('data', onData);
308
395
  socket?.removeListener('error', onError);
309
396
  socket?.removeListener('end', onEnd);
310
- if (reset) this.resetSocket(socket);
397
+ if (dispatched) this.outstandingDispatched = Math.max(0, this.outstandingDispatched - 1);
398
+ if (disposition === 'reset') this.resetSocket(socket);
399
+ else if (disposition === 'drain' && socket) this.retireForDrain(socket, normalized.maxResponseBytes);
311
400
  callback();
312
401
  };
313
- const fail = (error: unknown, reset = true): void => {
402
+ const fail = (error: unknown, disposition: 'keep' | 'reset' | 'drain' = 'reset'): void => {
314
403
  const normalizedError = normalizeTransportError(error);
315
404
  const classified = dispatched && mayHaveEffects ? markOutcomeUnknown(normalizedError) : normalizedError;
316
- finish(() => reject(classified), reset);
405
+ finish(() => reject(classified), disposition);
317
406
  };
318
- const onAbort = (): void => fail(transportError('EXTERNAL_PLUGIN_ABORTED', 'External provider request was cancelled.'));
407
+ const onAbort = (): void => fail(
408
+ transportError('EXTERNAL_PLUGIN_ABORTED', 'External provider request was cancelled.'),
409
+ dispatched ? 'drain' : 'reset',
410
+ );
319
411
  const onError = (error: Error): void => fail(transportError('EXTERNAL_PLUGIN_SOCKET_UNAVAILABLE', error.message));
320
412
  const onEnd = (): void => fail(transportError('EXTERNAL_PLUGIN_PROTOCOL_ERROR', 'External provider closed the socket before returning a complete response.'));
321
413
  const onData = (chunk: Buffer): void => {
@@ -338,14 +430,22 @@ export class ExternalUnixJsonlChannel {
338
430
  finish(() => resolve(decoded));
339
431
  } catch (error) {
340
432
  if (error instanceof ExternalUnixJsonlTransportError && error.source === 'provider') {
341
- fail(error, false);
433
+ fail(error, 'keep');
342
434
  } else {
343
435
  fail(error);
344
436
  }
345
437
  }
346
438
  };
347
439
 
348
- timer = setTimeout(() => fail(transportError('EXTERNAL_PLUGIN_TIMEOUT', `External provider request timed out after ${normalized.timeoutMs}ms.`)), normalized.timeoutMs);
440
+ // A request the caller stopped waiting for is not a reason to kill the
441
+ // provider: retire the connection into a bounded drain instead.
442
+ timer = setTimeout(
443
+ () => fail(
444
+ transportError('EXTERNAL_PLUGIN_TIMEOUT', `External provider request timed out after ${normalized.timeoutMs}ms.`),
445
+ dispatched ? 'drain' : 'reset',
446
+ ),
447
+ normalized.timeoutMs,
448
+ );
349
449
  timer.unref?.();
350
450
  options.signal?.addEventListener('abort', onAbort, { once: true });
351
451
 
@@ -361,7 +461,7 @@ export class ExternalUnixJsonlChannel {
361
461
  'EXTERNAL_PLUGIN_CHANNEL_GENERATION_CHANGED',
362
462
  `External provider connection changed from generation ${expectedGeneration} to ${this.generation}; renegotiate before executing the action.`,
363
463
  { retryable: true },
364
- ), false);
464
+ ), 'keep');
365
465
  return;
366
466
  }
367
467
  socket = this.socket;
@@ -373,6 +473,8 @@ export class ExternalUnixJsonlChannel {
373
473
  socket.once('error', onError);
374
474
  socket.once('end', onEnd);
375
475
  dispatched = true;
476
+ this.outstandingDispatched += 1;
477
+ this.outstandingMaxResponseBytes = normalized.maxResponseBytes;
376
478
  socket.write(normalized.envelope, (error) => {
377
479
  if (error) fail(transportError('EXTERNAL_PLUGIN_TRANSPORT_FAILED', error.message));
378
480
  });
@@ -399,21 +501,32 @@ export async function callExternalUnixJsonl(
399
501
  let dispatched = false;
400
502
  let buffer = Buffer.alloc(0);
401
503
 
402
- const cleanup = (): void => {
504
+ const cleanup = (disposition: 'destroy' | 'drain'): void => {
403
505
  if (timer) clearTimeout(timer);
404
506
  options.signal?.removeEventListener('abort', onAbort);
405
- if (socket && !socket.destroyed) socket.destroy();
507
+ if (!socket || socket.destroyed) return;
508
+ if (disposition === 'drain') {
509
+ // The socket is dead to this one-shot caller, so only the drain reader
510
+ // may keep observing it.
511
+ socket.removeAllListeners('data');
512
+ socket.removeAllListeners('error');
513
+ socket.removeAllListeners('end');
514
+ socket.removeAllListeners('close');
515
+ drainUnansweredResponse({ socket, maxResponseBytes: normalized.maxResponseBytes, onFinished: () => undefined });
516
+ return;
517
+ }
518
+ socket.destroy();
406
519
  };
407
- const finish = (callback: () => void): void => {
520
+ const finish = (callback: () => void, disposition: 'destroy' | 'drain' = 'destroy'): void => {
408
521
  if (settled) return;
409
522
  settled = true;
410
- cleanup();
523
+ cleanup(disposition);
411
524
  callback();
412
525
  };
413
- const fail = (error: unknown): void => {
526
+ const fail = (error: unknown, disposition: 'destroy' | 'drain' = 'destroy'): void => {
414
527
  const normalizedError = normalizeTransportError(error);
415
528
  const classified = dispatched && mayHaveEffects ? markOutcomeUnknown(normalizedError) : normalizedError;
416
- finish(() => reject(classified));
529
+ finish(() => reject(classified), disposition);
417
530
  };
418
531
  const succeed = (raw: string): void => finish(() => {
419
532
  try {
@@ -422,9 +535,20 @@ export async function callExternalUnixJsonl(
422
535
  reject(error);
423
536
  }
424
537
  });
425
- const onAbort = (): void => fail(transportError('EXTERNAL_PLUGIN_ABORTED', 'External provider request was cancelled.'));
538
+ const onAbort = (): void => fail(
539
+ transportError('EXTERNAL_PLUGIN_ABORTED', 'External provider request was cancelled.'),
540
+ dispatched ? 'drain' : 'destroy',
541
+ );
426
542
 
427
- timer = setTimeout(() => fail(transportError('EXTERNAL_PLUGIN_TIMEOUT', `External provider request timed out after ${normalized.timeoutMs}ms.`)), normalized.timeoutMs);
543
+ // Preserve the provider lifecycle: an abandoned request is drained instead
544
+ // of being answered with a closed connection.
545
+ timer = setTimeout(
546
+ () => fail(
547
+ transportError('EXTERNAL_PLUGIN_TIMEOUT', `External provider request timed out after ${normalized.timeoutMs}ms.`),
548
+ dispatched ? 'drain' : 'destroy',
549
+ ),
550
+ normalized.timeoutMs,
551
+ );
428
552
  timer.unref?.();
429
553
  options.signal?.addEventListener('abort', onAbort, { once: true });
430
554
 
@@ -114,7 +114,33 @@ export interface ComputerConsoleUnlockRequest {
114
114
  credentialHandle: string;
115
115
  }
116
116
 
117
- export type ComputerConsoleUnlockCommandRequest = ComputerConsoleUnlockPrepareRequest | ComputerConsoleUnlockRequest;
117
+ export interface ComputerConsoleUnlockEnrollRequest {
118
+ capability: typeof COMPUTER_CONSOLE_UNLOCK_CAPABILITY;
119
+ action: 'console_unlock_enroll';
120
+ }
121
+
122
+ export interface ComputerConsoleUnlockStatusRequest {
123
+ capability: typeof COMPUTER_CONSOLE_UNLOCK_CAPABILITY;
124
+ action: 'console_unlock_status';
125
+ }
126
+
127
+ export interface ComputerConsoleUnlockRecoverRequest {
128
+ capability: typeof COMPUTER_CONSOLE_UNLOCK_CAPABILITY;
129
+ action: 'console_unlock_recover';
130
+ }
131
+
132
+ export interface ComputerConsoleUnlockRevokeRequest {
133
+ capability: typeof COMPUTER_CONSOLE_UNLOCK_CAPABILITY;
134
+ action: 'console_unlock_revoke';
135
+ }
136
+
137
+ export type ComputerConsoleUnlockCommandRequest =
138
+ | ComputerConsoleUnlockPrepareRequest
139
+ | ComputerConsoleUnlockRequest
140
+ | ComputerConsoleUnlockEnrollRequest
141
+ | ComputerConsoleUnlockStatusRequest
142
+ | ComputerConsoleUnlockRecoverRequest
143
+ | ComputerConsoleUnlockRevokeRequest;
118
144
 
119
145
  export interface ComputerConsoleUnlockAuthorization {
120
146
  kind: 'explicit_single_use';
@@ -6,13 +6,13 @@ import {
6
6
  existsSync,
7
7
  mkdirSync,
8
8
  openSync,
9
- readFileSync,
10
9
  renameSync,
11
10
  writeFileSync,
12
11
  } from 'fs';
13
12
  import { dirname, join, resolve } from 'path';
14
13
  import { fileURLToPath } from 'url';
15
14
  import { resolveRepoPreferredControllerHome } from '../src/cli/repositories/controller-home';
15
+ import { findRegisteredRepositoryByCheckoutRoot } from '../src/cli/repositories/registry';
16
16
  import { cleanupTerminalWork } from '../src/runtime/control-plane/execution/work-terminal-cleanup';
17
17
  import { listWorkHandles, type WorkTerminalOutcome } from '../src/runtime/control-plane/execution/work-handle-store';
18
18
  import { runProcess } from '../src/effects/process-runner';
@@ -114,13 +114,12 @@ function assertCleanMain(repoRoot: string, expectedHead?: string): string {
114
114
  return head;
115
115
  }
116
116
 
117
- function repositoryId(repoRoot: string): string {
118
- const configPath = join(repoRoot, '.ai', 'harness', 'repository.json');
119
- const parsed = JSON.parse(readFileSync(configPath, 'utf8')) as { repoId?: unknown };
120
- if (typeof parsed.repoId !== 'string' || !parsed.repoId.trim()) {
117
+ function repositoryId(repoRoot: string, controllerHome: string): string {
118
+ const repository = findRegisteredRepositoryByCheckoutRoot(repoRoot, controllerHome);
119
+ if (!repository?.repoId?.trim()) {
121
120
  throw new Error('SOURCE_BASELINE_REPOSITORY_ID_UNAVAILABLE');
122
121
  }
123
- return parsed.repoId.trim();
122
+ return repository.repoId.trim();
124
123
  }
125
124
 
126
125
  function statePath(controllerHome: string, requestId: string): string {
@@ -194,7 +193,7 @@ async function request(args: string[]): Promise<void> {
194
193
  const controllerHome = resolveRepoPreferredControllerHome(repoRoot, option(args, '--controller-home'));
195
194
  const requestId = safeId(option(args, '--request-id'));
196
195
  const expectedHead = assertCleanMain(repoRoot, option(args, '--expected-head'));
197
- const repoId = repositoryId(repoRoot);
196
+ const repoId = repositoryId(repoRoot, controllerHome);
198
197
  const requestedAt = new Date().toISOString();
199
198
  let state: SourceBaselineState = {
200
199
  schemaVersion: 1,
@@ -251,7 +250,7 @@ async function run(args: string[]): Promise<void> {
251
250
  const requestId = safeId(option(args, '--request-id'));
252
251
  const expectedHead = option(args, '--expected-head');
253
252
  if (!expectedHead) throw new Error('SOURCE_BASELINE_EXPECTED_HEAD_REQUIRED');
254
- const repoId = repositoryId(repoRoot);
253
+ const repoId = repositoryId(repoRoot, controllerHome);
255
254
  const requestedAt = new Date().toISOString();
256
255
  let state: SourceBaselineState = {
257
256
  schemaVersion: 1,
@@ -301,7 +300,6 @@ async function run(args: string[]): Promise<void> {
301
300
  const result = await cleanupTerminalWork({
302
301
  controllerHome,
303
302
  handle,
304
- targetBranch: 'main',
305
303
  deleteBranch: true,
306
304
  terminalOutcome: terminalOutcome(handle),
307
305
  failureReason: handle.failureReason ?? 'source baseline terminal cleanup reconciliation',