@moretea-labs/forge 1.8.0 → 1.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (695) hide show
  1. package/AGENTS.md +73 -7
  2. package/CHANGELOG.md +34 -0
  3. package/CLAUDE.md +17 -2
  4. package/CONTRIBUTING.md +3 -2
  5. package/README.en.md +24 -3
  6. package/README.md +10 -6
  7. package/README.zh-CN.md +5 -3
  8. package/THIRD_PARTY_NOTICES.md +1 -2
  9. package/adapters/chatgpt/browser-delivery-host.ts +7 -1
  10. package/adapters/chatgpt/browser-delivery-runtime.ts +531 -56
  11. package/adapters/chatgpt/controller-binding-store.ts +101 -22
  12. package/adapters/chatgpt/controller-round-host.ts +15 -25
  13. package/adapters/chatgpt/controller-round-settlement-store.ts +58 -4
  14. package/adapters/chatgpt/provider-delivery.ts +229 -2
  15. package/adapters/chatgpt/work-conversation-binding-store.ts +99 -54
  16. package/adapters/computer/chatgpt-extension-target.ts +708 -0
  17. package/adapters/computer/chrome-extension/background.js +541 -0
  18. package/adapters/computer/chrome-extension/content.js +402 -0
  19. package/adapters/computer/chrome-extension/core.js +24 -0
  20. package/adapters/computer/chrome-extension/manifest.json +32 -0
  21. package/adapters/computer/desktop-operator-discovery.ts +11 -31
  22. package/adapters/computer/desktop-operator-provider.ts +18 -6
  23. package/adapters/computer/interaction-target-authority.ts +178 -24
  24. package/adapters/mcp/access-mode.ts +18 -39
  25. package/adapters/mcp/auth.ts +2 -7
  26. package/adapters/mcp/instructions.ts +6 -5
  27. package/adapters/mcp/multi-repository.ts +10 -47
  28. package/adapters/mcp/oauth.ts +73 -0
  29. package/adapters/mcp/paths.ts +4 -1
  30. package/adapters/mcp/runtime-gateway/bounded-result-runtime.ts +62 -0
  31. package/adapters/mcp/runtime-gateway/cognition-settlement.ts +201 -0
  32. package/adapters/mcp/runtime-gateway/context-adapter.ts +490 -113
  33. package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +83 -0
  34. package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +20 -5
  35. package/adapters/mcp/runtime-gateway/core-capability-adapter.ts +258 -0
  36. package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +10 -27
  37. package/adapters/mcp/runtime-gateway/engineering-tool-contract.ts +15 -0
  38. package/adapters/mcp/runtime-gateway/execution-tools.ts +14 -54
  39. package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +2 -1
  40. package/adapters/mcp/runtime-gateway/plugin-adapter.ts +132 -47
  41. package/adapters/mcp/runtime-gateway/process-tools.ts +173 -23
  42. package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +16 -4
  43. package/adapters/mcp/runtime-gateway/recovery-adapter.ts +69 -52
  44. package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +4 -35
  45. package/adapters/mcp/runtime-gateway/result-adapter.ts +10 -4
  46. package/adapters/mcp/runtime-gateway/router.ts +19 -507
  47. package/adapters/mcp/runtime-gateway/routing-policy.ts +506 -0
  48. package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +15 -66
  49. package/adapters/mcp/runtime-gateway/runtime-readiness-observation.ts +218 -0
  50. package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +123 -178
  51. package/adapters/mcp/runtime-gateway/runtime-tools.ts +11 -5
  52. package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +37 -1
  53. package/adapters/mcp/runtime-gateway/shared-adapter.ts +20 -0
  54. package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +416 -270
  55. package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +140 -0
  56. package/adapters/mcp/runtime-gateway/work-adapter.ts +262 -3123
  57. package/adapters/mcp/runtime-gateway/work-controller-operations.ts +257 -0
  58. package/adapters/mcp/runtime-gateway/work-detail-projection.ts +60 -0
  59. package/adapters/mcp/runtime-gateway/work-input-wire-migration.ts +229 -0
  60. package/adapters/mcp/runtime-gateway/work-learning-operations.ts +145 -0
  61. package/adapters/mcp/runtime-gateway/work-list-projection.ts +38 -0
  62. package/adapters/mcp/runtime-gateway/work-plan-operations.ts +382 -0
  63. package/adapters/mcp/runtime-gateway/work-repair-adapter.ts +308 -0
  64. package/adapters/mcp/runtime-gateway/work-requirement-operations.ts +148 -0
  65. package/adapters/mcp/runtime-gateway/work-semantic-operations.ts +320 -0
  66. package/adapters/mcp/runtime-gateway/work-workflow-operations.ts +113 -0
  67. package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +180 -0
  68. package/adapters/mcp/server.ts +91 -26
  69. package/adapters/mcp/setup.ts +5 -13
  70. package/adapters/mcp/tool-mapping/access-tools.ts +0 -6
  71. package/adapters/mcp/tool-mapping/legacy-tool-service.ts +703 -3092
  72. package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +5 -10
  73. package/adapters/mcp/tool-mapping/repository-tools.ts +170 -213
  74. package/adapters/mcp/toolset-names.ts +11 -37
  75. package/adapters/mcp/toolset.ts +19 -92
  76. package/{src/cli → adapters}/mcp/transports/AGENTS.md +5 -5
  77. package/{src/cli → adapters}/mcp/transports/CLAUDE.md +5 -5
  78. package/adapters/mcp/transports/http-observation.ts +377 -0
  79. package/adapters/mcp/transports/http-post-lifecycle.ts +19 -0
  80. package/adapters/mcp/transports/http.ts +200 -683
  81. package/adapters/mcp/transports/oauth-http.ts +322 -0
  82. package/adapters/mcp/transports/session-registry.ts +6 -0
  83. package/adapters/mcp/tunnels/openai-secure-tunnel.ts +89 -5
  84. package/adapters/mcp/types.ts +0 -6
  85. package/assets/hooks/lib/session-state.sh +0 -38
  86. package/assets/hooks/post-bash.sh +1 -1
  87. package/assets/hooks/post-tool-observer.sh +0 -5
  88. package/assets/hooks/prompt-guard.sh +0 -55
  89. package/assets/partials/04-project-structure.partial.md +1 -1
  90. package/assets/partials/07-footer.partial.md +1 -1
  91. package/assets/partials-agents/02-operating-mode.partial.md +1 -1
  92. package/assets/partials-agents/08-deep-docs.partial.md +1 -1
  93. package/assets/plugin-registry.v1.json +6 -4
  94. package/assets/reference-configs/agentic-development-flow.md +26 -1
  95. package/assets/reference-configs/external-tooling.md +0 -76
  96. package/assets/reference-configs/global-working-rules.md +19 -0
  97. package/assets/reference-configs/release-deploy.md +1 -1
  98. package/assets/templates/helpers/architecture-queue.sh +1 -1
  99. package/assets/templates/helpers/check-agent-tooling.sh +1 -327
  100. package/assets/templates/helpers/check-task-workflow.sh +1 -1
  101. package/assets/templates/helpers/ensure-task-workflow.sh +0 -14
  102. package/assets/templates/helpers/migrate-project-template.sh +2 -2
  103. package/assets/workflow-contract.v1.json +0 -2
  104. package/docs/README.md +5 -2
  105. package/docs/architecture/CURRENT.md +205 -51
  106. package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +14 -5
  107. package/docs/architecture/decisions/20260823-immediate-controller-relay.md +6 -3
  108. package/docs/architecture/decisions/20260904-ios-device-migration-baseline.md +42 -0
  109. package/docs/architecture/decisions/20260907-assistant-learning-loop.md +2 -0
  110. package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +19 -4
  111. package/docs/architecture/decisions/20260916-workflow-supervisor-authority.md +249 -0
  112. package/docs/architecture/decisions/20260917-cognitive-memory-foundation.md +82 -0
  113. package/docs/architecture/decisions/20260918-stable-candidate-release-lifecycle.md +234 -0
  114. package/docs/architecture/decisions/20260919-autonomous-work-liveness.md +62 -0
  115. package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +74 -0
  116. package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +342 -0
  117. package/docs/architecture/decisions/20261005-forge-v3-desktop-client-boundary.md +77 -0
  118. package/docs/architecture/decisions/20261009-exact-code-context-discovery.md +19 -0
  119. package/docs/architecture/decisions/20261009-generated-xcode-cache-retention.md +37 -0
  120. package/docs/architecture/decisions/20261011-autonomous-continuation-convergence.md +597 -0
  121. package/docs/architecture/decisions/20261017-edit-session-finalization-reconciliation.md +17 -0
  122. package/docs/architecture/decisions/20261019-retire-host-skills.md +16 -0
  123. package/docs/architecture/diagrams/agentic-dev-plugin-architecture.html +1 -1
  124. package/docs/architecture/domains/public-surface.md +3 -5
  125. package/docs/architecture/domains/verification.md +6 -5
  126. package/docs/architecture/domains/workflow-engine.md +6 -0
  127. package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +3 -3
  128. package/docs/architecture/requests/2026-09-04-computer-plugin-workflow-taxonomy.md +4 -4
  129. package/docs/architecture/reviews/20261015-code-search-runtime-acceptance.md +75 -0
  130. package/docs/forge-plugin-management.md +16 -4
  131. package/docs/operations/controller-browser-plugin.md +23 -0
  132. package/docs/operations/controller-performance-and-502.md +17 -0
  133. package/docs/operations/controller-reliability-runbook.md +2 -2
  134. package/docs/operations/features.md +6 -7
  135. package/docs/operations/features.zh-CN.md +1 -1
  136. package/docs/operations/github-repository.md +4 -4
  137. package/docs/operations/github-semantic-release-projection.md +20 -0
  138. package/docs/operations/homebrew.md +2 -2
  139. package/docs/operations/mcp-tool-exposure.md +13 -52
  140. package/docs/operations/releasing.md +2 -0
  141. package/docs/operations/runtime-performance-diagnostics.md +8 -0
  142. package/docs/operations/standalone-disaster-recovery.md +15 -7
  143. package/docs/tutorials/01-install-and-start.zh-CN.md +1 -1
  144. package/docs/tutorials/03-first-repository-task.md +2 -0
  145. package/docs/wiki/Computer-and-Plugins.md +78 -0
  146. package/docs/wiki/Computer-and-Plugins.zh-CN.md +88 -0
  147. package/docs/wiki/Home.md +16 -2
  148. package/docs/wiki/Implementation.md +25 -13
  149. package/docs/wiki/Installation.md +28 -32
  150. package/docs/wiki/Integrations.md +4 -0
  151. package/docs/wiki/Quick-Start.md +35 -22
  152. package/docs/wiki/Releases-and-Upgrades.md +15 -25
  153. package/docs/wiki/_Sidebar.md +5 -1
  154. package/package.json +25 -25
  155. package/packages/kernel/cognition/api/index.ts +6 -0
  156. package/packages/kernel/cognition/application/activation-service.ts +451 -0
  157. package/packages/kernel/cognition/application/consolidation-service.ts +185 -0
  158. package/packages/kernel/cognition/application/legacy-experience-adapter.ts +38 -0
  159. package/packages/kernel/cognition/application/memory-service.ts +64 -0
  160. package/packages/kernel/cognition/domain/learning.ts +106 -0
  161. package/packages/kernel/cognition/domain/memory.ts +254 -0
  162. package/packages/kernel/controller/api/index.ts +1 -0
  163. package/packages/kernel/controller/application/continuation-service.ts +281 -0
  164. package/packages/kernel/controller/application/controller-round-service.ts +12 -0
  165. package/packages/kernel/controller/domain/controller-round-transition-policy.ts +242 -21
  166. package/packages/kernel/controller/domain/controller-round.ts +4 -1
  167. package/packages/kernel/controller/domain/execution-quality.ts +3 -1
  168. package/packages/kernel/controller/infrastructure/controller-round-store.ts +689 -103
  169. package/packages/kernel/controller/infrastructure/controller-session-store.ts +348 -97
  170. package/packages/kernel/controller/ports/controller-host.ts +2 -0
  171. package/packages/kernel/identity/api/index.ts +10 -0
  172. package/packages/kernel/identity/domain/activity-projection.ts +43 -0
  173. package/packages/kernel/identity/domain/capability-broker.ts +60 -0
  174. package/packages/kernel/identity/domain/grant.ts +72 -0
  175. package/packages/kernel/identity/domain/owned-resource.ts +116 -0
  176. package/packages/kernel/identity/domain/user-request.ts +93 -0
  177. package/packages/kernel/identity/infrastructure/activity-projection-store.ts +87 -0
  178. package/packages/kernel/identity/infrastructure/capability-broker.ts +81 -0
  179. package/packages/kernel/identity/infrastructure/grant-store.ts +284 -0
  180. package/packages/kernel/identity/infrastructure/owned-resource-store.ts +259 -0
  181. package/packages/kernel/identity/infrastructure/user-request-store.ts +182 -0
  182. package/packages/kernel/scheduler/api/index.ts +0 -2
  183. package/packages/kernel/scheduler/application/eligibility.ts +4 -1
  184. package/packages/kernel/scheduler/application/schedule-service.ts +3 -0
  185. package/packages/kernel/scheduler/application/settlement.ts +0 -15
  186. package/packages/kernel/scheduler/domain/schedule.ts +87 -0
  187. package/packages/kernel/scheduler/infrastructure/schedule-store.ts +166 -143
  188. package/packages/kernel/work/api/index.ts +3 -2
  189. package/packages/kernel/work/application/work-service.ts +18 -42
  190. package/packages/kernel/work/domain/current-task-lineage.ts +104 -0
  191. package/packages/kernel/work/domain/engineering-design.ts +10 -5
  192. package/packages/kernel/work/domain/engineering-profile.ts +8 -12
  193. package/packages/kernel/work/domain/evaluation-promotion-receipt.ts +186 -0
  194. package/packages/kernel/work/domain/execution-concurrency.ts +19 -26
  195. package/packages/kernel/work/domain/execution-snapshot.ts +0 -31
  196. package/packages/kernel/work/domain/implementation-review.ts +14 -331
  197. package/packages/kernel/work/domain/objective-graph.ts +119 -0
  198. package/packages/kernel/work/domain/project-engineering-contract.ts +23 -1
  199. package/packages/kernel/work/domain/repository-completion-receipt.ts +1 -1
  200. package/packages/kernel/work/domain/state-machine.ts +34 -65
  201. package/packages/kernel/work/domain/types.ts +57 -51
  202. package/packages/kernel/work/infrastructure/work-contract-store.ts +847 -729
  203. package/packages/kernel/work/ports/work-contract-store.ts +5 -2
  204. package/packages/plugin-runtime/browser/provider-registry.ts +12 -36
  205. package/packages/plugin-runtime/browser/session-authority.ts +2 -1
  206. package/packages/plugin-runtime/computer/chatgpt-identity.ts +24 -0
  207. package/packages/plugin-runtime/computer/conversation-target.ts +153 -0
  208. package/packages/plugin-runtime/computer/index.ts +2 -0
  209. package/packages/plugin-runtime/computer/target-authority.ts +26 -1
  210. package/packages/plugin-runtime/external/unix-jsonl-transport.ts +142 -18
  211. package/packages/protocols/computer/contract.ts +27 -1
  212. package/scripts/activate-source-baseline.ts +7 -9
  213. package/scripts/assemble-template.ts +11 -72
  214. package/scripts/canary-controller-semantic-wait.ts +12 -24
  215. package/scripts/check-mcp-compatibility.ts +94 -201
  216. package/scripts/check-package-identity.mjs +0 -5
  217. package/scripts/check-runtime-architecture.mjs +921 -239
  218. package/scripts/forge-local-recovery-helper.mjs +93 -15
  219. package/scripts/init-project.sh +0 -46
  220. package/scripts/install-ios-hid-toolchain.sh +60 -0
  221. package/scripts/install-standalone-recovery.ts +1 -1
  222. package/scripts/lib/project-init-lib.sh +6 -3
  223. package/scripts/migrate-windows-wsl-controller-home.ts +2 -0
  224. package/scripts/open-source-audit-allowlist.txt +1 -3
  225. package/scripts/run-bounded-command.mjs +5 -0
  226. package/scripts/run-governed-gate.ts +2 -1
  227. package/scripts/run-mobile-monitor-bridge.ts +0 -1
  228. package/scripts/smoke-control-plane-failure-domain.ts +94 -0
  229. package/scripts/smoke-ios-physical-device.ts +38 -10
  230. package/scripts/smoke-mcp-http-runtime.ts +12 -8
  231. package/scripts/smoke-mcp-tool-surface.ts +27 -41
  232. package/scripts/smoke-runtime-recovery.ts +12 -43
  233. package/scripts/smoke-schedule-engine.ts +23 -15
  234. package/scripts/smoke-unattended-transport-recovery.ts +223 -0
  235. package/scripts/smoke-user-request-continuation-restart.ts +232 -0
  236. package/scripts/smoke-workflow-supervisor-chrome-adapter.ts +95 -0
  237. package/scripts/smoke-workflow-supervisor-process-restart.ts +276 -0
  238. package/scripts/smoke-workflow-supervisor-restart-recovery.ts +150 -0
  239. package/scripts/smoke-workflow-supervisor.ts +103 -0
  240. package/scripts/sync-generated-authority.mjs +0 -1
  241. package/scripts/verify-forge-runtime.sh +2 -1
  242. package/src/cli/agent-jobs/executor-health.ts +12 -35
  243. package/src/cli/agent-jobs/integration.ts +20 -51
  244. package/src/cli/agent-jobs/job-manager.ts +7 -3
  245. package/src/cli/chatgpt-browser/file-policy.ts +2 -2
  246. package/src/cli/commands/brain-assistant.ts +27 -13
  247. package/src/cli/commands/brain.ts +13 -15
  248. package/src/cli/commands/chatgpt.ts +1 -163
  249. package/src/cli/commands/doctor.ts +1 -143
  250. package/src/cli/commands/global-runtime.ts +3 -196
  251. package/src/cli/commands/init-hook.ts +6 -23
  252. package/src/cli/commands/init.ts +3 -252
  253. package/src/cli/commands/mcp.ts +0 -5
  254. package/src/cli/commands/prompt-guard-decision.ts +0 -2
  255. package/src/cli/commands/recovery.ts +137 -135
  256. package/src/cli/commands/repository.ts +17 -1
  257. package/src/cli/commands/runtime.ts +3 -3
  258. package/src/cli/commands/setup-execution.ts +41 -0
  259. package/src/cli/commands/setup-profile.ts +8 -0
  260. package/src/cli/controller/check-runner.ts +13 -2
  261. package/src/cli/controller/completion-backlog.ts +3 -3
  262. package/src/cli/controller/completion-orchestrator.ts +5 -44
  263. package/src/cli/controller/completion-target.ts +3 -72
  264. package/src/cli/controller/composite-operations.ts +1 -1
  265. package/src/cli/controller/context/instruction-context.ts +1 -1
  266. package/src/cli/controller/context/known-paths.ts +2 -2
  267. package/src/cli/controller/context/query-planning.ts +11 -4
  268. package/src/cli/controller/context/rule-resolution.ts +2 -2
  269. package/src/cli/controller/context/source-materializer.ts +83 -102
  270. package/src/cli/controller/context/structural-provider.ts +84 -0
  271. package/src/cli/controller/context/structural.ts +6 -6
  272. package/src/cli/controller/context/types.ts +8 -9
  273. package/src/cli/controller/context-pack.ts +107 -84
  274. package/src/cli/controller/execution-completion.ts +4 -7
  275. package/src/cli/controller/execution-policy.ts +36 -153
  276. package/src/cli/controller/governance.ts +2 -3
  277. package/src/cli/controller/issue-store.ts +4 -99
  278. package/src/cli/controller/launch-agents.ts +59 -18
  279. package/src/cli/controller/operational-plan.ts +25 -52
  280. package/src/cli/controller/runtime-config.ts +5 -1
  281. package/src/cli/controller/stuck-state-migration.ts +2 -3
  282. package/src/cli/controller/systemd-user.ts +42 -10
  283. package/src/cli/editing/edit-session.ts +18 -12
  284. package/src/cli/github/github.ts +4 -4
  285. package/src/cli/github/semantic-projection.ts +174 -0
  286. package/src/cli/hook/prompt-intents.ts +0 -9
  287. package/src/cli/index.ts +1 -43
  288. package/src/cli/local-bridge/connector-freshness.ts +1 -12
  289. package/src/cli/local-bridge/console-automations.ts +19 -14
  290. package/src/cli/local-bridge/console-view-models.ts +4 -13
  291. package/src/cli/local-bridge/facade-api.ts +64 -193
  292. package/src/cli/local-bridge/server.ts +24 -147
  293. package/src/cli/local-bridge/types.ts +0 -1
  294. package/src/cli/mcp/oauth-client-retirement.ts +74 -0
  295. package/src/cli/repositories/command-classifier.ts +0 -9
  296. package/src/cli/repositories/command-executor.ts +29 -23
  297. package/src/cli/repositories/command-scope.ts +37 -18
  298. package/src/cli/repositories/controller-home.ts +48 -0
  299. package/src/cli/repositories/ephemeral-workspace.ts +20 -30
  300. package/src/cli/repositories/git-command-executor.ts +2 -2
  301. package/src/cli/repositories/locks.ts +20 -0
  302. package/src/cli/repositories/registry.ts +79 -12
  303. package/src/cli/repositories/safe-patch.ts +2 -12
  304. package/src/cli/repositories/structured-git.ts +101 -5
  305. package/src/cli/repository/inspector.ts +185 -343
  306. package/src/cli/repository/session-cache.ts +92 -6
  307. package/src/effects/process-runner.ts +17 -1
  308. package/src/runtime/context/assistant-context.ts +20 -7
  309. package/src/runtime/context/assistant-work-context.ts +89 -27
  310. package/src/runtime/context/automatic-learning.ts +565 -0
  311. package/src/runtime/context/cognitive-attention.ts +173 -0
  312. package/src/runtime/context/cognitive-skill-canary.ts +158 -0
  313. package/src/runtime/context/context-closure.ts +46 -9
  314. package/src/runtime/context/context-pack-process.ts +103 -0
  315. package/src/runtime/context/context-plane.ts +1 -9
  316. package/src/runtime/context/direct-controller-learning.ts +298 -0
  317. package/src/runtime/context/generic-lsp-provider.ts +1 -1
  318. package/src/runtime/context/semantic-navigation-contract.ts +16 -0
  319. package/src/runtime/context/semantic-navigation.ts +7 -35
  320. package/src/runtime/context/typescript-navigation-process.ts +145 -0
  321. package/src/runtime/context/typescript-navigation.ts +89 -3
  322. package/src/runtime/control-plane/cleanup-artifact-retention.ts +215 -12
  323. package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +9 -47
  324. package/src/runtime/control-plane/execution/controller-authority-recovery.ts +34 -4
  325. package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +29 -20
  326. package/src/runtime/control-plane/execution/execution-identity.ts +23 -3
  327. package/src/runtime/control-plane/execution/repository-work-attribution.ts +7 -30
  328. package/src/runtime/control-plane/execution/retained-work-resume.ts +206 -199
  329. package/src/runtime/control-plane/execution/session-store.ts +31 -1
  330. package/src/runtime/control-plane/execution/validation.ts +6 -8
  331. package/src/runtime/control-plane/execution/work-authority-reconciler.ts +13 -42
  332. package/src/runtime/control-plane/execution/work-check-evidence.ts +137 -0
  333. package/src/runtime/control-plane/execution/work-completion-authority.ts +30 -85
  334. package/src/runtime/control-plane/execution/work-delivery-service.ts +616 -0
  335. package/src/runtime/control-plane/execution/work-evidence-policy.ts +12 -50
  336. package/src/runtime/control-plane/execution/work-execution-support.ts +50 -149
  337. package/src/runtime/control-plane/execution/work-handle-authority.ts +197 -110
  338. package/src/runtime/control-plane/execution/work-handle-store.ts +72 -44
  339. package/src/runtime/control-plane/execution/work-head-settlement.ts +53 -20
  340. package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +52 -29
  341. package/src/runtime/control-plane/execution/work-operation-service.ts +60 -34
  342. package/src/runtime/control-plane/execution/work-preparation-service.ts +231 -267
  343. package/src/runtime/control-plane/execution/work-process-evidence.ts +2 -2
  344. package/src/runtime/control-plane/execution/work-remote-delivery.ts +2 -3
  345. package/src/runtime/control-plane/execution/work-revision-diff.ts +39 -0
  346. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +201 -199
  347. package/src/runtime/control-plane/execution/work-validation-reconciler.ts +33 -85
  348. package/src/runtime/control-plane/execution/work-verification-service.ts +406 -50
  349. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +6 -2
  350. package/src/runtime/control-plane/facade/capability-registry.ts +364 -37
  351. package/src/runtime/control-plane/facade/check-normalization.ts +3 -9
  352. package/src/runtime/control-plane/facade/codex-delegation.ts +10 -11
  353. package/src/runtime/control-plane/facade/controller-connection.ts +135 -0
  354. package/src/runtime/control-plane/facade/goal-workloop-access.ts +1 -20
  355. package/src/runtime/control-plane/facade/goal-workloop.ts +281 -1753
  356. package/src/runtime/control-plane/facade/handoff-inbox-application.ts +12 -25
  357. package/src/runtime/control-plane/facade/handoff-inbox-store.ts +256 -52
  358. package/src/runtime/control-plane/facade/index.ts +0 -1
  359. package/src/runtime/control-plane/facade/operation-digest.ts +12 -15
  360. package/src/runtime/control-plane/facade/plan-contract-store.ts +451 -991
  361. package/src/runtime/control-plane/facade/policy-gate.ts +0 -23
  362. package/src/runtime/control-plane/facade/repository-work-admission.ts +12 -22
  363. package/src/runtime/control-plane/facade/requirement-authority.ts +102 -199
  364. package/src/runtime/control-plane/facade/requirement-board.ts +3 -3
  365. package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +51 -14
  366. package/src/runtime/control-plane/facade/self-healing-loop.ts +18 -53
  367. package/src/runtime/control-plane/facade/suggested-actions.ts +15 -18
  368. package/src/runtime/control-plane/facade/types.ts +49 -108
  369. package/src/runtime/control-plane/facade/work-continuation.ts +9 -9
  370. package/src/runtime/control-plane/generated-cache-retention.ts +206 -59
  371. package/src/runtime/control-plane/global-scheduler/autonomous-continuation.ts +248 -0
  372. package/src/runtime/control-plane/global-scheduler/durable-admission.ts +1 -1
  373. package/src/runtime/control-plane/global-scheduler/maintenance.ts +256 -117
  374. package/src/runtime/control-plane/global-scheduler/reconciliation.ts +3 -12
  375. package/src/runtime/control-plane/global-scheduler/scheduler.ts +66 -40
  376. package/src/runtime/control-plane/global-scheduler/wake-signal.ts +42 -2
  377. package/src/runtime/control-plane/governance/access-policy.ts +19 -2
  378. package/src/runtime/control-plane/governance/authorization.ts +20 -3
  379. package/src/runtime/control-plane/governance/external-effects.ts +1 -1
  380. package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +63 -300
  381. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +29 -300
  382. package/src/runtime/control-plane/launcher/local-conversation-controller.ts +238 -0
  383. package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +5 -2
  384. package/src/runtime/control-plane/launcher/thin-launcher.ts +96 -240
  385. package/src/runtime/control-plane/persistence/cognition-store.ts +820 -0
  386. package/src/runtime/control-plane/persistence/experience-store.ts +162 -29
  387. package/src/runtime/control-plane/persistence/requirement-store.ts +216 -74
  388. package/src/runtime/control-plane/persistence/sqlite-store.ts +113 -6
  389. package/src/runtime/control-plane/release-retention.ts +135 -47
  390. package/src/runtime/control-plane/repository-namespace-retention.ts +2 -2
  391. package/src/runtime/control-plane/runtime-cleanup.ts +295 -107
  392. package/src/runtime/control-plane/workspace/project-onboarding.ts +80 -0
  393. package/src/runtime/control-plane/workspace/semantic-sync-service.ts +19 -5
  394. package/src/runtime/control-plane/workspace/workspace-store.ts +169 -0
  395. package/src/runtime/diagnostics/incident-repair.ts +313 -146
  396. package/src/runtime/diagnostics/mcp-timing.ts +114 -0
  397. package/src/runtime/evidence/artifact-store.ts +158 -40
  398. package/src/runtime/evidence/evidence-store.ts +112 -8
  399. package/src/runtime/evidence/output-handle-index.ts +225 -0
  400. package/src/runtime/evidence/result-store.ts +158 -44
  401. package/src/runtime/evidence/sensitive-output.ts +22 -2
  402. package/src/runtime/execution/jobs/child-reference.ts +11 -0
  403. package/src/runtime/execution/jobs/receipt-recovery.ts +1 -11
  404. package/src/runtime/execution/jobs/store.ts +3 -4
  405. package/src/runtime/execution/managed-workspace.ts +57 -0
  406. package/src/runtime/execution/process-runtime/check-facade.ts +1 -1
  407. package/src/runtime/execution/process-runtime/check-result-retention.ts +2 -2
  408. package/src/runtime/execution/process-runtime/check-result.ts +105 -1
  409. package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +18 -8
  410. package/src/runtime/execution/process-runtime/command-facade.ts +82 -30
  411. package/src/runtime/execution/process-runtime/gc.ts +15 -2
  412. package/src/runtime/execution/process-runtime/handle-index.ts +176 -0
  413. package/src/runtime/execution/process-runtime/host-command-lane.ts +139 -0
  414. package/src/runtime/execution/process-runtime/index.ts +3 -0
  415. package/src/runtime/execution/process-runtime/lightweight-managed.ts +251 -72
  416. package/src/runtime/execution/process-runtime/persisted-check.ts +3 -3
  417. package/src/runtime/execution/process-runtime/process-runner-entry.ts +47 -5
  418. package/src/runtime/execution/process-runtime/process-scope.ts +160 -0
  419. package/src/runtime/execution/process-runtime/resource-claims.ts +65 -61
  420. package/src/runtime/execution/process-runtime/runtime.ts +55 -18
  421. package/src/runtime/execution/process-runtime/store.ts +30 -2
  422. package/src/runtime/execution/process-runtime/types.ts +6 -1
  423. package/src/runtime/execution/thin-harness/execution-router.ts +16 -16
  424. package/src/runtime/execution/thin-harness/fast-executor.ts +2 -2
  425. package/src/runtime/execution/thin-harness/search-worker.ts +2 -2
  426. package/src/runtime/execution/workers/executor.ts +3 -8
  427. package/src/runtime/maintenance/cleanup.ts +41 -5
  428. package/src/runtime/platform/service-inventory.ts +130 -0
  429. package/src/runtime/platform/service-manager.ts +8 -0
  430. package/src/runtime/plugins/action-application.ts +97 -29
  431. package/src/runtime/plugins/app-store-connect-adapter.ts +290 -18
  432. package/src/runtime/plugins/browser-adapter.ts +1124 -333
  433. package/src/runtime/plugins/browser-automation-service.ts +23 -3
  434. package/src/runtime/plugins/browser-macos-bridge.ts +431 -137
  435. package/src/runtime/plugins/browser-manifest-surface.ts +47 -12
  436. package/src/runtime/plugins/browser-native-session-service.ts +63 -13
  437. package/src/runtime/plugins/browser-registration.ts +18 -0
  438. package/src/runtime/plugins/browser-runtime.ts +40 -36
  439. package/src/runtime/plugins/browser-session-authority.ts +2 -2
  440. package/src/runtime/plugins/browser-session-store.ts +46 -76
  441. package/src/runtime/plugins/capability-authorization-grants.ts +258 -62
  442. package/src/runtime/plugins/computer-chatgpt-browser-adapter-installer.ts +228 -0
  443. package/src/runtime/plugins/computer-registration.ts +298 -20
  444. package/src/runtime/plugins/desktop-operator-external-policy.ts +36 -4
  445. package/src/runtime/plugins/desktop-operator-registration.ts +12 -4
  446. package/src/runtime/plugins/external-adapter.ts +42 -6
  447. package/src/runtime/plugins/external-registration.ts +21 -1
  448. package/src/runtime/plugins/github-adapter.ts +30 -3
  449. package/src/runtime/plugins/gmail-adapter.ts +189 -3
  450. package/src/runtime/plugins/google-calendar-adapter.ts +2 -2
  451. package/src/runtime/plugins/google-shared.ts +24 -12
  452. package/src/runtime/plugins/google-tasks-adapter.ts +2 -2
  453. package/src/runtime/plugins/ios/remote-xpc-hid.ts +70 -30
  454. package/src/runtime/plugins/ios-adapter.ts +46 -41
  455. package/src/runtime/plugins/ios-agent-device.ts +54 -4
  456. package/src/runtime/plugins/ios-device-ownership.ts +103 -0
  457. package/src/runtime/plugins/ios-physical-device.ts +497 -79
  458. package/src/runtime/plugins/lightweight-action.ts +208 -2
  459. package/src/runtime/plugins/local-system-adapter.ts +12 -100
  460. package/src/runtime/plugins/managed-process-adapter.ts +12 -5
  461. package/src/runtime/plugins/plugin-action-sidecar.ts +17 -13
  462. package/src/runtime/plugins/plugin-management-adapter.ts +1 -1
  463. package/src/runtime/plugins/store.ts +682 -435
  464. package/src/runtime/plugins/types.ts +24 -0
  465. package/src/runtime/plugins/xiaohongshu-publish.ts +16 -0
  466. package/src/runtime/projections/git-status-sampler.ts +2 -19
  467. package/src/runtime/projections/invalidation.ts +7 -3
  468. package/src/runtime/projections/materialized-view.ts +80 -36
  469. package/src/runtime/recovery/actions.ts +4 -4
  470. package/src/runtime/recovery/capability-action-application.ts +46 -45
  471. package/src/runtime/recovery/lifecycle-inventory.ts +30 -40
  472. package/src/runtime/recovery/maintenance-executor.ts +374 -123
  473. package/src/runtime/recovery/probe.ts +2 -2
  474. package/src/runtime/recovery/store.ts +29 -11
  475. package/src/runtime/release/release-coordinator.ts +312 -0
  476. package/src/runtime/release/release-session.ts +716 -0
  477. package/src/runtime/release/release-state-migration.ts +25 -0
  478. package/src/runtime/resources/leases/store.ts +56 -25
  479. package/src/runtime/root/computer-composition.ts +191 -6
  480. package/src/runtime/root/controller-progression-composition.ts +254 -0
  481. package/src/runtime/root/controller-round-composition.ts +20 -1
  482. package/src/runtime/root/deployment-topology.ts +106 -0
  483. package/src/runtime/root/entry.ts +4 -3
  484. package/src/runtime/root/known-good-recovery.ts +184 -0
  485. package/src/runtime/root/local-bridge.ts +0 -1
  486. package/src/runtime/root/mcp-transport.ts +111 -18
  487. package/src/runtime/root/ownership.ts +261 -9
  488. package/src/runtime/root/package-connector-service.ts +227 -29
  489. package/src/runtime/root/package-runtime-release.ts +117 -30
  490. package/src/runtime/root/package-runtime-service.ts +24 -24
  491. package/src/runtime/root/release-execution-canary.ts +57 -12
  492. package/src/runtime/root/release-loader.ts +90 -8
  493. package/src/runtime/root/release-manifest.ts +80 -40
  494. package/src/runtime/root/release-materialize.ts +372 -106
  495. package/src/runtime/root/release-store.ts +395 -36
  496. package/src/runtime/root/runtime-lane.ts +191 -0
  497. package/src/runtime/root/runtime.ts +160 -29
  498. package/src/runtime/root/scheduled-controller-composition.ts +29 -3
  499. package/src/runtime/root/service-runner.ts +2 -2
  500. package/src/runtime/root/service.ts +126 -44
  501. package/src/runtime/root/status.ts +48 -0
  502. package/src/runtime/root/types.ts +32 -9
  503. package/src/runtime/root/workflow-supervisor-composition.ts +681 -0
  504. package/src/runtime/root/workflow-supervisor-runtime.ts +564 -0
  505. package/src/runtime/root/write-fence.ts +50 -2
  506. package/src/runtime/safe-tooling/google-credential-store.ts +67 -22
  507. package/src/runtime/safe-tooling/google-oauth-broker.ts +25 -7
  508. package/src/runtime/safe-tooling/ios-development.ts +22 -8
  509. package/src/runtime/safe-tooling/job-summary.ts +1 -1
  510. package/src/runtime/safe-tooling/workspace-auth.ts +5 -2
  511. package/src/runtime/shared/atomic-text-file.ts +21 -0
  512. package/src/runtime/shared/bounded-child-supervisor.ts +9 -1
  513. package/src/runtime/shared/json-files.ts +8 -3
  514. package/src/runtime/shared/process-environment.ts +20 -9
  515. package/src/runtime/shared/response-budget.ts +1 -3
  516. package/src/runtime/standalone-recovery/controller-home-migration.ts +16 -24
  517. package/src/runtime/standalone-recovery/core.ts +3792 -417
  518. package/src/runtime/standalone-recovery/entry.ts +507 -45
  519. package/src/runtime/standalone-recovery/installer.ts +262 -148
  520. package/src/runtime/standalone-recovery/mcp-server.ts +29 -193
  521. package/src/runtime/standalone-recovery/operation-lock.ts +12 -2
  522. package/src/runtime/standalone-recovery/performance.ts +54 -16
  523. package/src/runtime/standalone-recovery/release.ts +53 -5
  524. package/src/runtime/standalone-recovery/service-labels.ts +5 -2
  525. package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +5 -2
  526. package/src/runtime/workflow/schedules/browser-probe.ts +17 -6
  527. package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +11 -3
  528. package/src/runtime/workflow/schedules/engine.ts +166 -178
  529. package/src/runtime/workflow/schedules/pending-activation.ts +11 -4
  530. package/src/runtime/workflow/schedules/work-continuation.ts +95 -11
  531. package/src/runtime/workflows/runtime.ts +15 -19
  532. package/src/testing/test-governance.ts +5 -1
  533. package/supervisor/chatgpt-conversation.ts +23 -0
  534. package/supervisor/client.ts +218 -0
  535. package/supervisor/control-plane.ts +963 -0
  536. package/supervisor/entry.ts +15 -0
  537. package/supervisor/forge-validators.ts +147 -0
  538. package/supervisor/index.ts +5 -0
  539. package/supervisor/native-browser-adapter.ts +1151 -0
  540. package/supervisor/native-messaging/host.ts +58 -0
  541. package/supervisor/native-messaging/manifest.ts +26 -0
  542. package/supervisor/native-messaging/protocol.ts +27 -0
  543. package/supervisor/paths.ts +18 -0
  544. package/supervisor/protocol.ts +250 -0
  545. package/supervisor/server.ts +412 -0
  546. package/supervisor/store.ts +1870 -0
  547. package/supervisor/tsconfig.json +8 -0
  548. package/supervisor/types.ts +261 -0
  549. package/SKILL.md +0 -427
  550. package/adapters/chatgpt/controller-host.ts +0 -119
  551. package/adapters/mcp/controller-round-compatibility.ts +0 -184
  552. package/adapters/mcp/frozen-client-semantic-compatibility.ts +0 -292
  553. package/adapters/mcp/runtime-gateway/work-compat-adapter.ts +0 -502
  554. package/adapters/mcp/runtime-gateway/work-validation-reconciler.ts +0 -1
  555. package/adapters/mcp/toolset-selection.ts +0 -41
  556. package/agents/openai.yaml +0 -4
  557. package/assets/skill-hooks.json +0 -41
  558. package/assets/skill-version.json +0 -189
  559. package/assets/skills/claude-review/SKILL.md +0 -231
  560. package/assets/skills/codex-review/SKILL.md +0 -103
  561. package/assets/templates/helpers/check-skill-version.ts +0 -193
  562. package/packages/kernel/progression/api/index.ts +0 -2
  563. package/packages/kernel/progression/application/projector.ts +0 -211
  564. package/packages/kernel/progression/domain/types.ts +0 -116
  565. package/packages/kernel/progression/index.ts +0 -1
  566. package/packages/kernel/scheduler/application/continuation-service.ts +0 -212
  567. package/packages/kernel/scheduler/domain/continuation.ts +0 -38
  568. package/packages/kernel/scheduler/infrastructure/continuation-dispatch-store.ts +0 -38
  569. package/packages/kernel/work/domain/admission-policy.ts +0 -34
  570. package/scripts/benchmark-background-check-overlap.ts +0 -228
  571. package/scripts/benchmark-computer-hotpath.ts +0 -255
  572. package/scripts/benchmark-controller-hotpath.ts +0 -212
  573. package/scripts/benchmark-controller-round2.ts +0 -191
  574. package/scripts/benchmark-ios-agent-device.ts +0 -511
  575. package/scripts/benchmark-mcp-host.sh +0 -117
  576. package/scripts/benchmark-mcp-transport.ts +0 -169
  577. package/scripts/benchmark-operational-memory-activation.ts +0 -235
  578. package/scripts/benchmark-operational-shadow.ts +0 -28
  579. package/scripts/benchmark-quality-harness.ts +0 -146
  580. package/scripts/benchmark-route-session-concurrency.ts +0 -915
  581. package/scripts/benchmark-thin-harness-gateway-ab.ts +0 -632
  582. package/scripts/benchmark-thin-harness-mcp-e2e.ts +0 -498
  583. package/scripts/benchmark-thin-harness.ts +0 -251
  584. package/scripts/benchmark-typescript-navigation.ts +0 -186
  585. package/scripts/benchmark-work-efficiency.ts +0 -334
  586. package/scripts/build-controller-ui.ts +0 -28
  587. package/scripts/check-npm-release.sh +0 -32
  588. package/scripts/check-public-release-surface.sh +0 -19
  589. package/scripts/check-release-published.sh +0 -57
  590. package/scripts/check-release-readiness.sh +0 -37
  591. package/scripts/check-release-version.mjs +0 -74
  592. package/scripts/check-skill-version.ts +0 -5
  593. package/scripts/check-tarball-install-smoke.sh +0 -150
  594. package/scripts/ensure-codegraph.sh +0 -16
  595. package/scripts/package-source-archive.sh +0 -147
  596. package/scripts/public-release-files.txt +0 -39
  597. package/scripts/public-release.ts +0 -174
  598. package/scripts/publish-release-tarball.sh +0 -27
  599. package/scripts/route-nl-vs-ts-eval.ts +0 -679
  600. package/scripts/run-skill-hook.ts +0 -244
  601. package/scripts/stage-runtime-release.ts +0 -44
  602. package/scripts/sync-codex-installed-copies.sh +0 -182
  603. package/src/cli/commands/tools.ts +0 -167
  604. package/src/cli/controller/progress.ts +0 -656
  605. package/src/cli/controller/work-mode.ts +0 -181
  606. package/src/cli/local-bridge/console-assets.ts +0 -17
  607. package/src/cli/local-bridge/dashboard.ts +0 -17
  608. package/src/cli/local-bridge/frontend/src/App.tsx +0 -10
  609. package/src/cli/local-bridge/frontend/src/components/Button.tsx +0 -1
  610. package/src/cli/local-bridge/frontend/src/components/DetailPane.tsx +0 -3
  611. package/src/cli/local-bridge/frontend/src/components/SearchField.tsx +0 -1
  612. package/src/cli/local-bridge/frontend/src/components/SectionHeader.tsx +0 -1
  613. package/src/cli/local-bridge/frontend/src/components/Segmented.tsx +0 -1
  614. package/src/cli/local-bridge/frontend/src/components/StatusText.tsx +0 -3
  615. package/src/cli/local-bridge/frontend/src/design/icons.tsx +0 -11
  616. package/src/cli/local-bridge/frontend/src/design/tokens.css +0 -8
  617. package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +0 -153
  618. package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +0 -37
  619. package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +0 -183
  620. package/src/cli/local-bridge/frontend/src/features/repositories/RepositoriesView.tsx +0 -2
  621. package/src/cli/local-bridge/frontend/src/features/system/SystemView.tsx +0 -2
  622. package/src/cli/local-bridge/frontend/src/features/work/WorkView.tsx +0 -4
  623. package/src/cli/local-bridge/frontend/src/lib/api.ts +0 -30
  624. package/src/cli/local-bridge/frontend/src/lib/format.ts +0 -4
  625. package/src/cli/local-bridge/frontend/src/lib/routes.ts +0 -7
  626. package/src/cli/local-bridge/frontend/src/main.tsx +0 -1
  627. package/src/cli/local-bridge/frontend/src/shell/AppShell.tsx +0 -1
  628. package/src/cli/local-bridge/frontend/src/shell/CommandBar.tsx +0 -2
  629. package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +0 -4
  630. package/src/cli/local-bridge/frontend/src/styles.css +0 -28
  631. package/src/cli/local-bridge/frontend/src/types.ts +0 -15
  632. package/src/cli/local-bridge/frontend/src/vite-env.d.ts +0 -1
  633. package/src/cli/local-bridge/frontend/vite.config.ts +0 -27
  634. package/src/cli/local-bridge/ui-dist/app.css +0 -1
  635. package/src/cli/local-bridge/ui-dist/app.js +0 -11228
  636. package/src/cli/mcp/access-mode.ts +0 -2
  637. package/src/cli/mcp/access-tools.ts +0 -2
  638. package/src/cli/mcp/audit.ts +0 -2
  639. package/src/cli/mcp/auth.ts +0 -2
  640. package/src/cli/mcp/instructions.ts +0 -2
  641. package/src/cli/mcp/legacy-context.ts +0 -2
  642. package/src/cli/mcp/legacy-tool-service.ts +0 -2
  643. package/src/cli/mcp/multi-repository.ts +0 -2
  644. package/src/cli/mcp/oauth.ts +0 -2
  645. package/src/cli/mcp/openai-secure-tunnel.ts +0 -2
  646. package/src/cli/mcp/paths.ts +0 -2
  647. package/src/cli/mcp/policy.ts +0 -2
  648. package/src/cli/mcp/post-finalize-work-attribution.ts +0 -2
  649. package/src/cli/mcp/proxy-env.ts +0 -2
  650. package/src/cli/mcp/readiness-projection.ts +0 -2
  651. package/src/cli/mcp/redaction.ts +0 -2
  652. package/src/cli/mcp/repo.ts +0 -2
  653. package/src/cli/mcp/repository-tools.ts +0 -2
  654. package/src/cli/mcp/server.ts +0 -2
  655. package/src/cli/mcp/setup.ts +0 -2
  656. package/src/cli/mcp/tool-capability-cache.ts +0 -2
  657. package/src/cli/mcp/tool-contract.ts +0 -2
  658. package/src/cli/mcp/tools.ts +0 -2
  659. package/src/cli/mcp/toolset-names.ts +0 -2
  660. package/src/cli/mcp/toolset-selection.ts +0 -2
  661. package/src/cli/mcp/toolset.ts +0 -2
  662. package/src/cli/mcp/transports/http.ts +0 -2
  663. package/src/cli/mcp/transports/session-registry.ts +0 -2
  664. package/src/cli/mcp/transports/stdio.ts +0 -2
  665. package/src/cli/mcp/types.ts +0 -2
  666. package/src/cli/mcp/umbrella-tools.ts +0 -2
  667. package/src/cli/tools/codegraph.ts +0 -695
  668. package/src/core/adoption/helper-wrapper-plan.ts +0 -159
  669. package/src/runtime/context/codegraph-cache-boundary.ts +0 -255
  670. package/src/runtime/context/codegraph-read-provider.ts +0 -611
  671. package/src/runtime/context/codegraph-sidecar.cjs +0 -248
  672. package/src/runtime/control-plane/codegraph-cache-retention.ts +0 -164
  673. package/src/runtime/control-plane/execution/content-equivalent-commit-authority.ts +0 -169
  674. package/src/runtime/control-plane/execution/direct-canonical-work-reconciliation.ts +0 -85
  675. package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +0 -655
  676. package/src/runtime/control-plane/execution/work-finalization-service.ts +0 -2850
  677. package/src/runtime/control-plane/execution/work-path-scope.ts +0 -37
  678. package/src/runtime/control-plane/execution/work-task-receipt.ts +0 -468
  679. package/src/runtime/control-plane/facade/controller-round-relay.ts +0 -3
  680. package/src/runtime/control-plane/facade/work-admission-policy.ts +0 -142
  681. package/src/runtime/control-plane/facade/work-implementation-review.ts +0 -2
  682. package/src/runtime/control-plane/facade/work-state-machine.ts +0 -2
  683. package/src/runtime/control-plane/facade/work-task-projection.ts +0 -66
  684. package/src/runtime/control-plane/routing/index.ts +0 -1
  685. package/src/runtime/control-plane/routing/route-policy.ts +0 -401
  686. package/src/runtime/control-plane/routing/workspace-admission.ts +0 -70
  687. package/src/runtime/gateway/mcp/execution-tools.ts +0 -2
  688. package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +0 -2
  689. package/src/runtime/gateway/mcp/persisted-check-process.ts +0 -2
  690. package/src/runtime/gateway/mcp/process-tools.ts +0 -2
  691. package/src/runtime/gateway/mcp/router.ts +0 -2
  692. package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +0 -2
  693. package/src/runtime/gateway/mcp/runtime-tools.ts +0 -2
  694. package/src/runtime/gateway/mcp/work-validation-reconciler.ts +0 -2
  695. package/src/runtime/plugins/browser-provider-registry.ts +0 -2
@@ -2,16 +2,27 @@ import { randomUUID } from 'crypto';
2
2
  import { AsyncLocalStorage } from 'node:async_hooks';
3
3
  import type { ExecutionJobOrigin } from '../../src/runtime/execution/jobs/types';
4
4
  import { browserActions } from '../../src/runtime/plugins/browser-manifest-surface';
5
- import { controllerPluginRepository, executeControllerScopedPluginAction, getControllerPluginManifest, submitAssistantPluginAction } from '../../src/runtime/plugins/store';
5
+ import { executeControllerScopedPluginAction, getControllerPluginManifest, submitControllerPluginAction } from '../../src/runtime/plugins/store';
6
6
  import {
7
+ CHATGPT_AUTOMATION_RATE_LIMITED,
8
+ CHATGPT_AUTOMATION_RATE_LIMITED_AFTER_SUBMIT,
7
9
  CHATGPT_AUTOMATION_SUBMISSION_OUTCOME_UNKNOWN,
8
10
  ChatgptProviderDeliveryError,
11
+ chatgptProviderPageFailure,
9
12
  DEFAULT_CHATGPT_AUTOMATION_MODEL,
10
13
  type ChatgptAutomationReasoning,
11
14
  type ChatgptAutomationTabCleanupStatus,
15
+ type ChatgptProviderPageFailureCode,
12
16
  } from './provider-delivery';
13
17
 
14
- const DEFAULT_CHATGPT_AUTOMATION_PLUGIN_MENTION = '@forge';
18
+ // The installed/connected primary Forge plugin is `forge`, not the separate
19
+ // Plugin Creator package `forge-current-1-8-1` or the Forge Recovery app.
20
+ // Live ChatGPT selection yields an exact app:// ProseMirror Forge chip.
21
+ const CHATGPT_FORGE_PLUGIN_SLUG = 'forge';
22
+ const CHATGPT_FORGE_PLUGIN_LABEL = 'forge';
23
+ const CHATGPT_FORGE_PLUGIN_PATH = 'app://asdk_app_6ac09022b26081918f20ff868c773824';
24
+ const CHATGPT_PLUGIN_PICKER_OPTIONS = '[data-mention-section-id="plugins"] [data-mention-section-items] > button';
25
+
15
26
 
16
27
  type ChatgptBrowserActionOrigin = Pick<ExecutionJobOrigin, 'surface' | 'actor'>;
17
28
  interface ChatgptBrowserActionContext {
@@ -28,16 +39,20 @@ export function withChatgptBrowserActionOrigin<T>(
28
39
  return chatgptBrowserActionOrigin.run({ origin, authorizationGrantRefs }, operation);
29
40
  }
30
41
 
31
- function withForgePluginMention(prompt: string): string {
32
- const value = prompt.trim();
42
+ /** Strip the legacy text trigger; only a real ChatGPT app chip selects Forge. */
43
+ export function chatgptSupervisorPromptBody(prompt: string): string {
44
+ const value = prompt.trim().replace(/^@forge(?:[ \t]*\r?\n|[ \t]+|$)/i, '').trim();
33
45
  if (!value) throw new Error('CHATGPT_AUTOMATION_PROMPT_REQUIRED');
34
- if (/^@forge(?:\s|$)/i.test(value)) return value;
35
- return `${DEFAULT_CHATGPT_AUTOMATION_PLUGIN_MENTION} ${value}`;
46
+ return value;
36
47
  }
37
48
 
38
- const CHATGPT_PROMPT_SELECTOR = 'div#prompt-textarea[contenteditable="true"]';
39
- const CHATGPT_SEND_SELECTOR = '[data-testid="send-button"], button[aria-label*="Send"], button[data-testid*="send"]';
40
- const CHATGPT_USER_MESSAGE_SELECTOR = '[data-message-author-role="user"]';
49
+ // ChatGPT's composer is a ProseMirror textbox; the historical #prompt-textarea id is no longer stable.
50
+ // Bind delivery to the semantic composer contract used by the live UI so readiness, fill, and Enter fallback share one selector authority.
51
+ const CHATGPT_PROMPT_SELECTOR = '[data-composer-markdown][role="textbox"][contenteditable="true"]';
52
+ const CHATGPT_SEND_SELECTOR = '[data-testid="send-button"], button[aria-label="Send"], button[aria-label="发送"], button[data-testid*="send"]';
53
+ const CHATGPT_USER_MESSAGE_SELECTOR = '[data-message-author-role="user"], [data-chatgpt-search-unit-key$=":user"], [data-content-search-unit-key$=":user"]';
54
+ const CHATGPT_ASSISTANT_MESSAGE_SELECTOR = '[data-message-author-role="assistant"], [data-chatgpt-search-unit-key$=":assistant"], [data-content-search-unit-key$=":assistant"]';
55
+ const CHATGPT_STOP_GENERATING_SELECTOR = '[data-testid="stop-button"], button[aria-label*="Stop"]';
41
56
  const CHATGPT_INTELLIGENCE_CONTROL_SELECTORS = [
42
57
  'main button, main [role="button"]',
43
58
  'button, [role="button"]',
@@ -55,16 +70,15 @@ const CHATGPT_BROWSER_AUTHORIZATION_ACTIONS = new Set(
55
70
  .map((action) => action.actionId),
56
71
  );
57
72
 
58
- const CHATGPT_BROWSER_TRANSPORT_OVERRIDES = {
59
- browser_mode: 'attach_preferred',
60
- cdp_attach_fallback: 'fail_closed',
61
- native_attach_mode: 'auto',
62
- native_browser_candidates: ['chrome'],
63
- } as const;
64
-
65
73
  export function chatgptBrowserActionArgs(actionId: string, args: Record<string, unknown>): Record<string, unknown> {
66
- if (actionId === 'configure' || actionId === 'list_sessions' || actionId === 'reconcile_sessions') return args;
67
- return { ...args, ...CHATGPT_BROWSER_TRANSPORT_OVERRIDES };
74
+ // Browser transport policy is controller-scoped configuration. Do not copy
75
+ // it into every action envelope: older Browser action schemas legitimately
76
+ // reject these optional fields even though the persisted configuration still
77
+ // supports the same policy. Keeping the envelope action-specific also lets a
78
+ // resumed ChatGPT round cross a connector/schema rotation without failing
79
+ // before the provider can observe the conversation.
80
+ void actionId;
81
+ return args;
68
82
  }
69
83
 
70
84
  export function chatgptBrowserActionResult(envelope: Record<string, unknown>, actionId: string): Record<string, unknown> {
@@ -97,11 +111,7 @@ async function controllerBrowserAction(
97
111
  // reusable controller-scoped Browser grant. Scheduled delivery stays on the
98
112
  // low-level executor and must present explicit refs already bound to this Work.
99
113
  if (origin.surface === 'chatgpt-action' && CHATGPT_BROWSER_AUTHORIZATION_ACTIONS.has(actionId)) {
100
- const submitted = await submitAssistantPluginAction(
101
- controllerHome,
102
- controllerPluginRepository(controllerHome),
103
- actionRequest,
104
- );
114
+ const submitted = await submitControllerPluginAction(controllerHome, actionRequest);
105
115
  const grantId = submitted.authorization?.grantId?.trim();
106
116
  if (grantId) context?.authorizationGrantRefs.add(grantId);
107
117
  if (!submitted.result) throw new Error(`CHATGPT_BROWSER_ACTION_RESULT_INVALID:${actionId}`);
@@ -155,17 +165,31 @@ function normalizeChatgptOutboundText(value: string): string {
155
165
  const CHATGPT_OUTBOUND_MESSAGE_UI_SUFFIXES = ['收起', 'Collapse', 'Show less'] as const;
156
166
  const MAX_CHATGPT_OUTBOUND_VERIFICATION_CHARS = 100_000;
157
167
  const MIN_TRUNCATED_CHATGPT_OUTBOUND_PREFIX_CHARS = 256;
168
+ const CHATGPT_PROVIDER_ERROR_SELECTOR = '[role="alert"], [aria-live="assertive"], [data-testid*="error"], [data-testid*="toast"], [data-sonner-toast]';
169
+ const CHATGPT_DELIVERY_FAILURE_PROBE_INTERVAL_MS = 1_000;
170
+
171
+ interface BrowserFailedRequest {
172
+ url?: string;
173
+ method?: string;
174
+ status?: number;
175
+ failure?: string;
176
+ }
177
+
178
+ type ChatgptFailedRequestBaseline = Map<string, number>;
158
179
 
159
180
  export function chatgptOutboundMessageMatchesPrompt(
160
181
  messageText: string,
161
182
  prompt: string,
162
- options: { truncated?: boolean } = {},
183
+ options: { truncated?: boolean; boundForgePlugin?: boolean } = {},
163
184
  ): boolean {
164
185
  const message = normalizeChatgptOutboundText(messageText);
165
186
  const normalizedPrompt = normalizeChatgptOutboundText(prompt);
166
187
  if (!message || !normalizedPrompt) return false;
167
- if (message === normalizedPrompt) return true;
168
- if (CHATGPT_OUTBOUND_MESSAGE_UI_SUFFIXES.some((suffix) => message === `${normalizedPrompt} ${suffix}`)) return true;
188
+ const candidatePrompts = [normalizedPrompt,
189
+ ...(options.boundForgePlugin ? [`${normalizedPrompt} ${CHATGPT_FORGE_PLUGIN_LABEL}`] : []),
190
+ ];
191
+ if (candidatePrompts.some((candidate) => message === candidate)) return true;
192
+ if (candidatePrompts.some((candidate) => CHATGPT_OUTBOUND_MESSAGE_UI_SUFFIXES.some((suffix) => message === `${candidate} ${suffix}`))) return true;
169
193
  // Browser text extraction is deliberately bounded. A large ControllerRound
170
194
  // prompt can exceed that bound, so requiring exact equality makes successful
171
195
  // submissions mechanically unverifiable. Accept only an explicitly reported
@@ -173,7 +197,140 @@ export function chatgptOutboundMessageMatchesPrompt(
173
197
  // remains insufficient evidence.
174
198
  return options.truncated === true
175
199
  && message.length >= MIN_TRUNCATED_CHATGPT_OUTBOUND_PREFIX_CHARS
176
- && normalizedPrompt.startsWith(message);
200
+ && candidatePrompts.some((candidate) => candidate.startsWith(message));
201
+ }
202
+
203
+ export function chatgptAutomationDeliveryFailure(
204
+ bodyText: string | undefined,
205
+ ): ChatgptProviderPageFailureCode | undefined {
206
+ return chatgptProviderPageFailure(bodyText);
207
+ }
208
+
209
+ export function chatgptSubmissionSettlementWaitBudget(timeoutMs?: number): number {
210
+ return Math.min(Math.max(timeoutMs ?? 30_000, 3_000), 30_000);
211
+ }
212
+
213
+ export function chatgptSubmissionObservationDelayMs(observationIndex: number): number {
214
+ const schedule = [500, 1_000, 2_000, 3_000, 5_000] as const;
215
+ return schedule[Math.min(Math.max(0, Math.trunc(observationIndex)), schedule.length - 1)];
216
+ }
217
+
218
+ export function chatgptSubmissionAcceptanceObserved(input: {
219
+ outboundConfirmed: boolean;
220
+ hasConversationIdentity: boolean;
221
+ assistantResponseObserved: boolean;
222
+ generationInProgress: boolean;
223
+ }): boolean {
224
+ return input.outboundConfirmed
225
+ && input.hasConversationIdentity
226
+ && (input.assistantResponseObserved || input.generationInProgress);
227
+ }
228
+
229
+ export function chatgptComposerRetainsPrompt(
230
+ composerText: string | undefined,
231
+ prompt: string,
232
+ ): boolean {
233
+ if (composerText === undefined) return false;
234
+ const composer = normalizeChatgptOutboundText(composerText);
235
+ const expected = normalizeChatgptOutboundText(prompt);
236
+ return Boolean(composer && expected && composer === expected);
237
+ }
238
+
239
+ async function currentChatgptComposerText(
240
+ controllerHome: string,
241
+ workId: string,
242
+ browserSessionId: string,
243
+ timeoutMs?: number,
244
+ ): Promise<string | undefined> {
245
+ const result = await controllerBrowserAction(controllerHome, workId, 'get_text', {
246
+ session_id: browserSessionId,
247
+ selector: CHATGPT_PROMPT_SELECTOR,
248
+ max_chars: MAX_CHATGPT_OUTBOUND_VERIFICATION_CHARS,
249
+ timeout_ms: Math.min(timeoutMs ?? 3_000, 3_000),
250
+ }, timeoutMs).catch(() => undefined);
251
+ return typeof result?.text === 'string' ? result.text : undefined;
252
+ }
253
+
254
+ async function currentChatgptComposerHtml(
255
+ controllerHome: string,
256
+ workId: string,
257
+ browserSessionId: string,
258
+ timeoutMs?: number,
259
+ ): Promise<string | undefined> {
260
+ const result = await controllerBrowserAction(controllerHome, workId, 'get_html', {
261
+ session_id: browserSessionId,
262
+ selector: CHATGPT_PROMPT_SELECTOR,
263
+ max_chars: MAX_CHATGPT_OUTBOUND_VERIFICATION_CHARS,
264
+ timeout_ms: Math.min(timeoutMs ?? 3_000, 3_000),
265
+ }, timeoutMs).catch(() => undefined);
266
+ return typeof result?.text === 'string' && result.truncated !== true ? result.text : undefined;
267
+ }
268
+
269
+ /** A real ChatGPT plugin mention is a non-editable ProseMirror app chip, not @ text. */
270
+ export function chatgptForgePluginMentionBound(
271
+ composerHtml: string | undefined,
272
+ composerText: string | undefined,
273
+ prompt: string,
274
+ ): boolean {
275
+ if (!composerHtml || !composerText) return false;
276
+ // Name and path must belong to ONE real app chip, never to different
277
+ // elements in the same composer HTML. A plain @forge is not an invocation.
278
+ const chips = [...composerHtml.matchAll(/<[^>]*\b(?:plugin|app)-mention-name="[^"]+"[^>]*>/g)].map((match) => match[0]);
279
+ if (chips.length !== 1 || !chips[0]!.includes(`app-mention-name="${CHATGPT_FORGE_PLUGIN_SLUG}"`)
280
+ || !chips[0]!.includes(`app-mention-path="${CHATGPT_FORGE_PLUGIN_PATH}"`)) return false;
281
+ const normalized = normalizeChatgptOutboundText(composerText);
282
+ const payload = normalizeChatgptOutboundText(prompt);
283
+ return normalized === `${payload} ${CHATGPT_FORGE_PLUGIN_LABEL}`;
284
+ }
285
+
286
+ /** Return the single exact main-Forge suggestion after normalizing UI line breaks. */
287
+ export function chatgptForgePluginPickerIndex(labels: string[]): number | undefined {
288
+ const matches = labels.flatMap((label, index) => {
289
+ const value = normalizeChatgptOutboundText(label);
290
+ return value === CHATGPT_FORGE_PLUGIN_LABEL || value.startsWith(`${CHATGPT_FORGE_PLUGIN_LABEL} `)
291
+ ? [index] : [];
292
+ });
293
+ return matches.length === 1 ? matches[0] : undefined;
294
+ }
295
+
296
+ /** Browser owns DOM actions; Supervisor remains the only effect and delivery owner. */
297
+ async function bindChatgptForgePluginMention(
298
+ controllerHome: string,
299
+ workId: string,
300
+ browserSessionId: string,
301
+ prompt: string,
302
+ targetUrl: string,
303
+ timeoutMs?: number,
304
+ ): Promise<void> {
305
+ const baseArgs = { session_id: browserSessionId, timeout_ms: timeoutMs ?? 60_000 };
306
+ // The payload and final standalone @ paragraph were inserted together.
307
+ // ProseMirror drops the leading whitespace of a later ` @` insertion.
308
+ await controllerBrowserAction(controllerHome, workId, 'type', {
309
+ ...baseArgs, selector: CHATGPT_PROMPT_SELECTOR, text: CHATGPT_FORGE_PLUGIN_LABEL,
310
+ post_action_wait_ms: 120,
311
+ }, timeoutMs);
312
+ const entries = await controllerBrowserAction(controllerHome, workId, 'query_all', {
313
+ ...baseArgs, selector: CHATGPT_PLUGIN_PICKER_OPTIONS, limit: 80,
314
+ }, timeoutMs);
315
+ const index = chatgptForgePluginPickerIndex(queryMatches(entries).map(matchText));
316
+ if (index === undefined) {
317
+ throw new ChatgptProviderDeliveryError('CHATGPT_AUTOMATION_PLUGIN_NOT_IN_PICKER',
318
+ `CHATGPT_AUTOMATION_PLUGIN_NOT_IN_PICKER:${CHATGPT_FORGE_PLUGIN_SLUG}:${targetUrl}`,
319
+ { conversationUrl: targetUrl });
320
+ }
321
+ // The option order was observed from this exact open picker. Never select
322
+ // another Forge-prefixed app as a fallback; verify the resulting app chip.
323
+ await controllerBrowserAction(controllerHome, workId, 'click', {
324
+ ...baseArgs, selector: `${CHATGPT_PLUGIN_PICKER_OPTIONS}:nth-of-type(${index + 1})`,
325
+ }, timeoutMs);
326
+ const [composerHtml, composerText] = await Promise.all([
327
+ currentChatgptComposerHtml(controllerHome, workId, browserSessionId, timeoutMs),
328
+ currentChatgptComposerText(controllerHome, workId, browserSessionId, timeoutMs),
329
+ ]);
330
+ if (!chatgptForgePluginMentionBound(composerHtml, composerText, prompt)) {
331
+ throw new ChatgptProviderDeliveryError('CHATGPT_AUTOMATION_PLUGIN_MENTION_UNVERIFIED',
332
+ `CHATGPT_AUTOMATION_PLUGIN_MENTION_UNVERIFIED:${targetUrl}`, { conversationUrl: targetUrl });
333
+ }
177
334
  }
178
335
 
179
336
  async function latestChatgptUserMessage(
@@ -213,8 +370,138 @@ async function fullChatgptMessageText(
213
370
  };
214
371
  }
215
372
 
373
+ async function latestChatgptAssistantMessage(
374
+ controllerHome: string,
375
+ workId: string,
376
+ browserSessionId: string,
377
+ timeoutMs?: number,
378
+ ): Promise<{ selector?: string; preview: string }> {
379
+ const result = await controllerBrowserAction(controllerHome, workId, 'query_all', {
380
+ session_id: browserSessionId,
381
+ selector: CHATGPT_ASSISTANT_MESSAGE_SELECTOR,
382
+ limit: 1,
383
+ from_end: true,
384
+ timeout_ms: Math.min(timeoutMs ?? 3_000, 3_000),
385
+ }, timeoutMs);
386
+ const latest = queryMatches(result).at(-1);
387
+ return { selector: matchSelector(latest), preview: latest ? matchText(latest) : '' };
388
+ }
389
+
390
+ function chatgptMessageObservationChanged(
391
+ before: { selector?: string; preview: string },
392
+ latest: { selector?: string; preview: string },
393
+ ): boolean {
394
+ return Boolean(
395
+ (latest.selector && latest.selector !== before.selector)
396
+ || (!before.preview && latest.preview)
397
+ || latest.preview !== before.preview,
398
+ );
399
+ }
400
+
401
+ async function chatgptGenerationInProgress(
402
+ controllerHome: string,
403
+ workId: string,
404
+ browserSessionId: string,
405
+ timeoutMs?: number,
406
+ ): Promise<boolean> {
407
+ const result = await controllerBrowserAction(controllerHome, workId, 'query_all', {
408
+ session_id: browserSessionId,
409
+ selector: CHATGPT_STOP_GENERATING_SELECTOR,
410
+ limit: 1,
411
+ timeout_ms: Math.min(timeoutMs ?? 1_000, 1_000),
412
+ }, timeoutMs).catch(() => undefined);
413
+ return queryMatches(result).length > 0;
414
+ }
415
+
416
+ function failedRequestKey(request: BrowserFailedRequest): string {
417
+ return `${request.method?.toUpperCase() ?? ''}|${request.status ?? ''}|${request.url ?? ''}|${request.failure ?? ''}`;
418
+ }
419
+
420
+ /** Only provider requests causally inside the current send pipeline may classify that send as rate-limited. */
421
+ export function chatgptFailedRequestIsCausalRateLimit(request: Pick<BrowserFailedRequest, 'url' | 'method' | 'status'>): boolean {
422
+ if (request.status !== 429 || request.method?.trim().toUpperCase() !== 'POST') return false;
423
+ try {
424
+ const url = new URL(request.url ?? '');
425
+ if (url.protocol !== 'https:' || url.hostname !== 'chatgpt.com') return false;
426
+ const path = url.pathname.toLowerCase();
427
+ return /^\/backend-api\/(?:f\/)?conversation(?:\/|$)/.test(path)
428
+ || path === '/backend-api/sentinel/chat-requirements';
429
+ } catch {
430
+ return false;
431
+ }
432
+ }
433
+
434
+ async function chatgptFailedRequestBaseline(
435
+ controllerHome: string,
436
+ workId: string,
437
+ browserSessionId: string,
438
+ timeoutMs?: number,
439
+ ): Promise<ChatgptFailedRequestBaseline | undefined> {
440
+ const result = await controllerBrowserAction(controllerHome, workId, 'get_failed_requests', {
441
+ session_id: browserSessionId,
442
+ timeout_ms: Math.min(timeoutMs ?? 2_000, 2_000),
443
+ }, timeoutMs).catch(() => undefined);
444
+ if (!result || !Array.isArray(result.failedRequests)) return undefined;
445
+ const baseline = new Map<string, number>();
446
+ for (const request of result.failedRequests) {
447
+ if (!request || typeof request !== 'object') continue;
448
+ const key = failedRequestKey(request as BrowserFailedRequest);
449
+ baseline.set(key, (baseline.get(key) ?? 0) + 1);
450
+ }
451
+ return baseline;
452
+ }
453
+
454
+ async function chatgptProviderFailureOnErrorUi(
455
+ controllerHome: string,
456
+ workId: string,
457
+ browserSessionId: string,
458
+ timeoutMs?: number,
459
+ ): Promise<ChatgptProviderPageFailureCode | undefined> {
460
+ const result = await controllerBrowserAction(controllerHome, workId, 'query_all', {
461
+ session_id: browserSessionId,
462
+ selector: CHATGPT_PROVIDER_ERROR_SELECTOR,
463
+ limit: 20,
464
+ timeout_ms: Math.min(timeoutMs ?? 2_000, 2_000),
465
+ }, timeoutMs).catch(() => undefined);
466
+ for (const match of queryMatches(result)) {
467
+ const failure = chatgptAutomationDeliveryFailure(matchText(match));
468
+ if (failure) return failure;
469
+ }
470
+ return undefined;
471
+ }
472
+
473
+ async function chatgptDeliveryFailureOnPage(
474
+ controllerHome: string,
475
+ workId: string,
476
+ browserSessionId: string,
477
+ failedRequestBaseline: ChatgptFailedRequestBaseline | undefined,
478
+ timeoutMs?: number,
479
+ ): Promise<ChatgptProviderPageFailureCode | undefined> {
480
+ const uiFailure = await chatgptProviderFailureOnErrorUi(controllerHome, workId, browserSessionId, timeoutMs);
481
+ if (uiFailure) return uiFailure;
482
+ if (!failedRequestBaseline) return undefined;
483
+
484
+ const current = await controllerBrowserAction(controllerHome, workId, 'get_failed_requests', {
485
+ session_id: browserSessionId,
486
+ timeout_ms: Math.min(timeoutMs ?? 2_000, 2_000),
487
+ }, timeoutMs).catch(() => undefined);
488
+ if (!current || !Array.isArray(current.failedRequests)) return undefined;
489
+ const seen = new Map<string, number>();
490
+ for (const value of current.failedRequests) {
491
+ if (!value || typeof value !== 'object') continue;
492
+ const request = value as BrowserFailedRequest;
493
+ const key = failedRequestKey(request);
494
+ const occurrence = (seen.get(key) ?? 0) + 1;
495
+ seen.set(key, occurrence);
496
+ const baselineCount = failedRequestBaseline.get(key) ?? 0;
497
+ if (occurrence <= baselineCount) continue;
498
+ if (chatgptFailedRequestIsCausalRateLimit(request)) return CHATGPT_AUTOMATION_RATE_LIMITED;
499
+ }
500
+ return undefined;
501
+ }
502
+
216
503
  function chatgptSendControlUnavailable(error: unknown): boolean {
217
- return error instanceof Error && (error.message.includes('Selector') && error.message.includes('not found'));
504
+ return error instanceof Error && error.message.includes('PLUGIN_BROWSER_SELECTOR_UNAVAILABLE');
218
505
  }
219
506
 
220
507
  function normalizeExecutionControlLabel(label: string | undefined): string {
@@ -438,7 +725,7 @@ export async function ensureChatgptExecutionPreference(
438
725
  for (let index = 0; index < Math.abs(targetValue - currentValue); index += 1) {
439
726
  await controllerBrowserAction(controllerHome, workId, 'press', {
440
727
  session_id: browserSessionId,
441
- selector: CHATGPT_CAPABILITY_MENUITEM_SELECTOR,
728
+ selector: CHATGPT_CAPABILITY_SLIDER_SELECTOR,
442
729
  key: direction,
443
730
  timeout_ms: timeoutMs ?? 60_000,
444
731
  post_action_wait_ms: 120,
@@ -502,6 +789,42 @@ function chatgptUrlMatchesContinuationTarget(observedUrl: string, targetUrl: str
502
789
  }
503
790
  }
504
791
 
792
+ /** The saved Browser session id is not proof of the live native tab identity. */
793
+ export function chatgptBrowserObservationMatchesTarget(
794
+ observation: Record<string, unknown>,
795
+ browserSessionId: string,
796
+ targetUrl: string,
797
+ ): boolean {
798
+ const observedSessionId = stringField(observation.sessionId) ?? resultSessionId(observation);
799
+ if (observedSessionId && observedSessionId !== browserSessionId) return false;
800
+ const connection = observation.browserConnection;
801
+ const liveTab = connection && typeof connection === 'object'
802
+ ? (connection as Record<string, unknown>).tab : undefined;
803
+ const liveTabUrl = liveTab && typeof liveTab === 'object'
804
+ ? stringField((liveTab as Record<string, unknown>).url) : undefined;
805
+ const urls = [resultUrl(observation), liveTabUrl].filter((url): url is string => Boolean(url));
806
+ return urls.length > 0 && urls.every((url) => chatgptUrlMatchesContinuationTarget(url, targetUrl));
807
+ }
808
+
809
+ async function verifyChatgptExactSubmissionTab(
810
+ controllerHome: string,
811
+ workId: string,
812
+ browserSessionId: string,
813
+ targetUrl: string,
814
+ timeoutMs?: number,
815
+ ): Promise<void> {
816
+ const observed = await controllerBrowserAction(controllerHome, workId, 'get_text', {
817
+ session_id: browserSessionId,
818
+ selector: CHATGPT_PROMPT_SELECTOR,
819
+ max_chars: 1,
820
+ timeout_ms: Math.min(timeoutMs ?? 3_000, 3_000),
821
+ }, timeoutMs);
822
+ if (!chatgptBrowserObservationMatchesTarget(observed, browserSessionId, targetUrl)) {
823
+ throw new ChatgptProviderDeliveryError('CHATGPT_AUTOMATION_TARGET_IDENTITY_CHANGED',
824
+ `CHATGPT_AUTOMATION_TARGET_IDENTITY_CHANGED:${targetUrl}`, { conversationUrl: targetUrl });
825
+ }
826
+ }
827
+
505
828
  function completeChatgptBrowserInventorySessions(
506
829
  inventory: Record<string, unknown>,
507
830
  ): ChatgptBrowserSessionInventoryItem[] | undefined {
@@ -557,11 +880,19 @@ export async function closeChatgptAutomationTabAfterDispatch(
557
880
  workId: string,
558
881
  browserSessionId: string,
559
882
  timeoutMs?: number,
883
+ authorizationGrantRefs: readonly string[] = [],
560
884
  ): Promise<{ status: ChatgptAutomationTabCleanupStatus; error?: { code: string; message: string } }> {
561
885
  try {
562
- const closed = await controllerBrowserAction(controllerHome, workId, 'close_page', {
886
+ const closePage = () => controllerBrowserAction(controllerHome, workId, 'close_page', {
563
887
  session_id: browserSessionId,
564
888
  }, Math.min(timeoutMs ?? 15_000, 15_000));
889
+ const closed = authorizationGrantRefs.length > 0
890
+ ? await withChatgptBrowserActionOrigin(
891
+ { surface: 'schedule', actor: 'chatgpt-work-continuation' },
892
+ closePage,
893
+ new Set(authorizationGrantRefs),
894
+ )
895
+ : await closePage();
565
896
  if (closed.preservedUserOwnedTab === true) return { status: 'preserved_user_owned' };
566
897
  if (closed.resourceClosed === true) return { status: 'closed' };
567
898
  return { status: 'session_closed' };
@@ -588,6 +919,7 @@ export async function settleWorkChatgptAutomationTab(input: {
588
919
  workId: string;
589
920
  browserSessionId: string;
590
921
  timeoutMs?: number;
922
+ authorizationGrantRefs?: readonly string[];
591
923
  }): Promise<{ status: ChatgptAutomationTabCleanupStatus; error?: { code: string; message: string } }> {
592
924
  if (input.browserSessionId.startsWith('forge-chatgpt-bridge-')) return { status: 'session_closed' };
593
925
  return closeChatgptAutomationTabAfterDispatch(
@@ -595,6 +927,7 @@ export async function settleWorkChatgptAutomationTab(input: {
595
927
  input.workId,
596
928
  input.browserSessionId,
597
929
  input.timeoutMs,
930
+ input.authorizationGrantRefs,
598
931
  );
599
932
  }
600
933
 
@@ -632,6 +965,14 @@ export async function navigateWorkConversation(
632
965
  const opened = await controllerBrowserAction(controllerHome, workId, 'create_session', {
633
966
  session_id: sessionId,
634
967
  url,
968
+ // Direct Browser delivery must never silently escalate to the macOS
969
+ // Apple Events compatibility provider. Work-bound unattended delivery is
970
+ // owned by Workflow Supervisor's extension transport; this legacy direct
971
+ // lane uses a Forge-managed browser resource unless the caller explicitly
972
+ // configured a different transport elsewhere.
973
+ browser_mode: 'managed_persistent',
974
+ native_attach_mode: 'disabled',
975
+ cdp_attach_fallback: 'fail_closed',
635
976
  wait_until: 'domcontentloaded',
636
977
  timeout_ms: timeoutMs ?? 60_000,
637
978
  retries: 1,
@@ -665,6 +1006,13 @@ export async function navigateWorkConversation(
665
1006
  } catch (preflightError) {
666
1007
  if (!chatgptAutomationNavigationRequiresReplacement(preflightError)) throw preflightError;
667
1008
  const replacementSessionId = await openReplacement(browserSessionId, targetUrl);
1009
+ // create_session establishes only the session capability. Activating the
1010
+ // exact replacement page is an interaction-capability action, so an
1011
+ // interactive prepare also establishes the grant required by later
1012
+ // schedule-origin fill/click actions on this same origin.
1013
+ await controllerBrowserAction(controllerHome, workId, 'activate_page', {
1014
+ session_id: replacementSessionId,
1015
+ }, timeoutMs);
668
1016
  return { submissionTargetUrl: targetUrl, recoveredFromStaleBinding: true, browserSessionId: replacementSessionId };
669
1017
  }
670
1018
  await navigate(browserSessionId, targetUrl);
@@ -689,15 +1037,11 @@ export async function navigateWorkConversation(
689
1037
  const replacementSessionId = await openReplacement(browserSessionId, targetUrl);
690
1038
  return { submissionTargetUrl: targetUrl, recoveredFromStaleBinding: false, browserSessionId: replacementSessionId };
691
1039
  }
692
- if (!isChatgptConversationUrl(targetUrl)) throw error;
693
- try {
694
- await navigate(browserSessionId, 'https://chatgpt.com/');
695
- return { submissionTargetUrl: 'https://chatgpt.com/', recoveredFromStaleBinding: true, browserSessionId };
696
- } catch (fallbackError) {
697
- if (!chatgptAutomationNavigationRequiresReplacement(fallbackError)) throw fallbackError;
698
- const replacementSessionId = await openReplacement(browserSessionId, 'https://chatgpt.com/');
699
- return { submissionTargetUrl: 'https://chatgpt.com/', recoveredFromStaleBinding: true, browserSessionId: replacementSessionId };
700
- }
1040
+ // A bound /c/<id> is transport identity, not a hint. Falling back to the
1041
+ // ChatGPT root silently creates a replacement conversation and can turn one
1042
+ // transient navigation failure into duplicate provider recovery. Preserve the
1043
+ // exact conversation and let the owning continuation reconcile or retry it.
1044
+ throw error;
701
1045
  }
702
1046
  }
703
1047
 
@@ -709,17 +1053,62 @@ export async function submitChatgptPrompt(
709
1053
  targetUrl: string,
710
1054
  timeoutMs?: number,
711
1055
  ): Promise<string> {
712
- const renderedPrompt = withForgePluginMention(prompt);
713
- const before = await latestChatgptUserMessage(controllerHome, workId, browserSessionId, timeoutMs)
714
- .catch((): { selector?: string; preview: string; url?: string } => ({ selector: undefined, preview: '', url: targetUrl }));
1056
+ // Verify the live native tab before reading/sending. The saved session may
1057
+ // have retargeted while its Browser handle remained stable.
1058
+ await verifyChatgptExactSubmissionTab(
1059
+ controllerHome, workId, browserSessionId, targetUrl, timeoutMs,
1060
+ );
1061
+ const renderedPrompt = chatgptSupervisorPromptBody(prompt);
1062
+ const [before, beforeAssistant, failedRequestBaseline, preexistingPageFailure] = await Promise.all([
1063
+ latestChatgptUserMessage(controllerHome, workId, browserSessionId, timeoutMs)
1064
+ .catch((): { selector?: string; preview: string; url?: string } => ({ selector: undefined, preview: '', url: targetUrl })),
1065
+ latestChatgptAssistantMessage(controllerHome, workId, browserSessionId, timeoutMs)
1066
+ .catch((): { selector?: string; preview: string } => ({ selector: undefined, preview: '' })),
1067
+ chatgptFailedRequestBaseline(controllerHome, workId, browserSessionId, timeoutMs),
1068
+ chatgptProviderFailureOnErrorUi(controllerHome, workId, browserSessionId, timeoutMs),
1069
+ ]);
1070
+ if (preexistingPageFailure === CHATGPT_AUTOMATION_RATE_LIMITED) {
1071
+ throw new ChatgptProviderDeliveryError(
1072
+ CHATGPT_AUTOMATION_RATE_LIMITED,
1073
+ `${CHATGPT_AUTOMATION_RATE_LIMITED}:${targetUrl}`,
1074
+ { conversationUrl: targetUrl },
1075
+ );
1076
+ }
1077
+ const mentionTriggerDraft = `${renderedPrompt}\n@`;
715
1078
  await controllerBrowserAction(controllerHome, workId, 'fill', {
716
1079
  session_id: browserSessionId,
717
1080
  selector: CHATGPT_PROMPT_SELECTOR,
718
- text: renderedPrompt,
1081
+ text: mentionTriggerDraft,
719
1082
  timeout_ms: timeoutMs ?? 60_000,
720
1083
  post_action_wait_ms: 100,
721
1084
  }, timeoutMs);
722
1085
 
1086
+ // Browser fill can report success even when the live ProseMirror composer did
1087
+ // not retain the intended payload. Never send or trigger Enter fallback on
1088
+ // an unverified draft; the owning effect must remain unreplayed.
1089
+ const verifiedComposerText = await currentChatgptComposerText(
1090
+ controllerHome, workId, browserSessionId, timeoutMs,
1091
+ );
1092
+ if (!chatgptComposerRetainsPrompt(verifiedComposerText, mentionTriggerDraft)) {
1093
+ throw new ChatgptProviderDeliveryError(
1094
+ 'CHATGPT_AUTOMATION_COMPOSER_UNVERIFIED',
1095
+ `CHATGPT_AUTOMATION_COMPOSER_UNVERIFIED:${targetUrl}`,
1096
+ { conversationUrl: targetUrl },
1097
+ );
1098
+ }
1099
+
1100
+ // The immutable effect marker alone is not enough: choose the exact main
1101
+ // Forge app and verify its structured mention before sending the payload.
1102
+ await bindChatgptForgePluginMention(
1103
+ controllerHome, workId, browserSessionId, renderedPrompt, targetUrl, timeoutMs,
1104
+ );
1105
+
1106
+ // A popup or plugin-selection action can change the native tab. Re-attest
1107
+ // immediately before Send, never infer identity from a successful click.
1108
+ await verifyChatgptExactSubmissionTab(
1109
+ controllerHome, workId, browserSessionId, targetUrl, timeoutMs,
1110
+ );
1111
+
723
1112
  let observedUrl = targetUrl;
724
1113
  let submitOutcomeUnknown = false;
725
1114
  let observedNewOutbound = false;
@@ -733,9 +1122,46 @@ export async function submitChatgptPrompt(
733
1122
  observedUrl = resultUrl(sent) ?? observedUrl;
734
1123
  } catch (error) {
735
1124
  if (browserMutationOutcomeUnknown(error, 'click')) {
736
- // Never replay an outcome-unknown submit: semantic observation below decides
737
- // whether the original click committed, preventing duplicate user messages.
1125
+ // Never blind-replay an outcome-unknown submit. First reconcile the exact
1126
+ // provider state. If the same payload is still wholly present in the
1127
+ // composer, no new user message exists, and no conversation identity was
1128
+ // created, the original click is mechanically proven not to have committed.
1129
+ // Only then may the same provider dispatch resume Send once without
1130
+ // refilling the composer or creating a new semantic effect generation.
738
1131
  submitOutcomeUnknown = true;
1132
+ const latestAfterUnknown = await latestChatgptUserMessage(
1133
+ controllerHome,
1134
+ workId,
1135
+ browserSessionId,
1136
+ timeoutMs,
1137
+ ).catch(() => undefined);
1138
+ if (latestAfterUnknown) {
1139
+ observedUrl = latestAfterUnknown.url ?? observedUrl;
1140
+ observedNewOutbound = chatgptMessageObservationChanged(before, latestAfterUnknown);
1141
+ }
1142
+ const hasConversationIdentity = /\/c\/[^/?#]+/.test(observedUrl);
1143
+ const [composerHtml, composerText] = await Promise.all([
1144
+ currentChatgptComposerHtml(controllerHome, workId, browserSessionId, timeoutMs),
1145
+ currentChatgptComposerText(controllerHome, workId, browserSessionId, timeoutMs),
1146
+ ]);
1147
+ if (
1148
+ !observedNewOutbound
1149
+ && !hasConversationIdentity
1150
+ && chatgptForgePluginMentionBound(composerHtml, composerText, renderedPrompt)
1151
+ ) {
1152
+ try {
1153
+ const resumed = await controllerBrowserAction(controllerHome, workId, 'click', {
1154
+ session_id: browserSessionId,
1155
+ selector: CHATGPT_SEND_SELECTOR,
1156
+ timeout_ms: timeoutMs ?? 60_000,
1157
+ post_action_wait_ms: 250,
1158
+ }, timeoutMs);
1159
+ observedUrl = resultUrl(resumed) ?? observedUrl;
1160
+ submitOutcomeUnknown = false;
1161
+ } catch (resumeError) {
1162
+ if (!browserMutationOutcomeUnknown(resumeError, 'click')) throw resumeError;
1163
+ }
1164
+ }
739
1165
  } else if (chatgptSendControlUnavailable(error)) {
740
1166
  const pressed = await controllerBrowserAction(controllerHome, workId, 'press', {
741
1167
  session_id: browserSessionId,
@@ -750,28 +1176,78 @@ export async function submitChatgptPrompt(
750
1176
  }
751
1177
  }
752
1178
 
753
- const deadline = Date.now() + Math.min(Math.max(timeoutMs ?? 10_000, 3_000), 10_000);
1179
+ const deadline = Date.now() + chatgptSubmissionSettlementWaitBudget(timeoutMs);
1180
+ let nextFailureProbeAt = 0;
1181
+ let observationIndex = 0;
754
1182
  do {
755
1183
  const latest = await latestChatgptUserMessage(controllerHome, workId, browserSessionId, timeoutMs).catch(() => undefined);
756
1184
  if (latest) {
757
1185
  observedUrl = latest.url ?? observedUrl;
758
- const isNewOutbound = Boolean(
759
- (latest.selector && latest.selector !== before.selector)
760
- || (!before.preview && latest.preview)
761
- || latest.preview !== before.preview,
762
- );
1186
+ const isNewOutbound = chatgptMessageObservationChanged(before, latest);
763
1187
  if (isNewOutbound) {
764
1188
  observedNewOutbound = true;
765
1189
  const fullText = await fullChatgptMessageText(controllerHome, workId, browserSessionId, latest, timeoutMs);
766
- if (chatgptOutboundMessageMatchesPrompt(fullText.text, renderedPrompt, { truncated: fullText.truncated }) && /\/c\/[^/?#]+/.test(observedUrl)) {
767
- return observedUrl;
1190
+ const outboundConfirmed = chatgptOutboundMessageMatchesPrompt(fullText.text, renderedPrompt, { truncated: fullText.truncated, boundForgePlugin: true });
1191
+ const hasConversationIdentity = /\/c\/[^/?#]+/.test(observedUrl);
1192
+ if (outboundConfirmed && hasConversationIdentity) {
1193
+ const [latestAssistant, generationInProgress] = await Promise.all([
1194
+ latestChatgptAssistantMessage(controllerHome, workId, browserSessionId, timeoutMs).catch(() => undefined),
1195
+ chatgptGenerationInProgress(controllerHome, workId, browserSessionId, timeoutMs),
1196
+ ]);
1197
+ const assistantResponseObserved = Boolean(
1198
+ latestAssistant?.preview
1199
+ && chatgptMessageObservationChanged(beforeAssistant, latestAssistant),
1200
+ );
1201
+ if (chatgptSubmissionAcceptanceObserved({
1202
+ outboundConfirmed,
1203
+ hasConversationIdentity,
1204
+ assistantResponseObserved,
1205
+ generationInProgress,
1206
+ })) {
1207
+ return observedUrl;
1208
+ }
1209
+ if (Date.now() >= nextFailureProbeAt) {
1210
+ const deliveryFailure = await chatgptDeliveryFailureOnPage(
1211
+ controllerHome,
1212
+ workId,
1213
+ browserSessionId,
1214
+ failedRequestBaseline,
1215
+ timeoutMs,
1216
+ );
1217
+ if (deliveryFailure) {
1218
+ const failureCode = deliveryFailure === CHATGPT_AUTOMATION_RATE_LIMITED
1219
+ ? CHATGPT_AUTOMATION_RATE_LIMITED_AFTER_SUBMIT
1220
+ : deliveryFailure;
1221
+ throw new ChatgptProviderDeliveryError(
1222
+ failureCode,
1223
+ `${failureCode}:${observedUrl}`,
1224
+ { conversationUrl: observedUrl },
1225
+ );
1226
+ }
1227
+ nextFailureProbeAt = Date.now() + CHATGPT_DELIVERY_FAILURE_PROBE_INTERVAL_MS;
1228
+ }
768
1229
  }
769
1230
  }
770
1231
  }
771
- await new Promise((resolveWait) => setTimeout(resolveWait, 150));
1232
+ const remainingMs = deadline - Date.now();
1233
+ if (remainingMs <= 0) break;
1234
+ const observationDelayMs = chatgptSubmissionObservationDelayMs(observationIndex);
1235
+ observationIndex += 1;
1236
+ await new Promise((resolveWait) => setTimeout(resolveWait, Math.min(observationDelayMs, remainingMs)));
772
1237
  } while (Date.now() < deadline);
773
1238
  const hasConversationIdentity = /\/c\/[^/?#]+/.test(observedUrl);
774
- const failureCode = submitOutcomeUnknown || (observedNewOutbound && hasConversationIdentity)
1239
+ const finalComposerText = submitOutcomeUnknown && !observedNewOutbound && !hasConversationIdentity
1240
+ ? await currentChatgptComposerText(controllerHome, workId, browserSessionId, timeoutMs)
1241
+ : undefined;
1242
+ const submitProvablyNotApplied = submitOutcomeUnknown
1243
+ && !observedNewOutbound
1244
+ && !hasConversationIdentity
1245
+ && chatgptComposerRetainsPrompt(finalComposerText, renderedPrompt);
1246
+ // A fresh /c/<id> or any changed outbound user message is provider-side
1247
+ // evidence that the send may have committed even when DOM observation lagged.
1248
+ // Keep that ambiguity fenced. Conversely, an exact unchanged composer proves
1249
+ // the send did not commit and must not be mislabeled outcome_unknown.
1250
+ const failureCode = (submitOutcomeUnknown && !submitProvablyNotApplied) || hasConversationIdentity || observedNewOutbound
775
1251
  ? CHATGPT_AUTOMATION_SUBMISSION_OUTCOME_UNKNOWN
776
1252
  : 'CHATGPT_AUTOMATION_SUBMISSION_NOT_CONFIRMED';
777
1253
  throw new ChatgptProviderDeliveryError(
@@ -780,4 +1256,3 @@ export async function submitChatgptPrompt(
780
1256
  { conversationUrl: observedUrl },
781
1257
  );
782
1258
  }
783
-