@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
@@ -6,15 +6,16 @@ import { createInterface } from 'readline';
6
6
  import { performance } from 'perf_hooks';
7
7
  import { AssistantPluginError } from '../errors';
8
8
 
9
- const TOOLCHAIN_VERSION = '10.2.1';
9
+ export const IOS_HID_TOOLCHAIN_VERSION = '11.24.0';
10
10
  const WORKER_IDLE_MS = 15 * 60_000;
11
11
  const WORKER_STARTUP_MS = 12_000;
12
- const MUTATION_READY_BUDGET_MS = 2_500;
13
12
  const REQUEST_TIMEOUT_MS = 12_000;
14
13
  const RSD_ENDPOINT_CACHE_TTL_MS = 30_000;
15
14
  const RSD_ENDPOINT_PERSISTED_TTL_MS = 10 * 60_000;
16
15
  const MAX_TEXT_LENGTH = 2048;
17
16
  const MAX_STDERR = 8 * 1024;
17
+ const TOOLCHAIN_PROBE_TTL_MS = 60_000;
18
+ const TOOLCHAIN_PROBE_TIMEOUT_MS = 5_000;
18
19
 
19
20
  export interface RemoteXpcHidInput {
20
21
  controllerHome: string;
@@ -99,6 +100,7 @@ const warmups = new Map<string, Promise<void>>();
99
100
  const workerGenerations = new Map<string, number>();
100
101
  const warmupFailures = new Map<string, WarmupFailure>();
101
102
  const endpointCache = new Map<string, EndpointCacheEntry>();
103
+ const toolchainProbeCache = new Map<string, { checkedAt: number; installedVersion?: string; available: boolean; reason?: string }>();
102
104
 
103
105
  export function setRemoteXpcHidExecutorForTest(executor: TestExecutor | undefined): void {
104
106
  testExecutor = executor;
@@ -112,26 +114,71 @@ export function resetRemoteXpcHidForTest(): void {
112
114
  workerGenerations.clear();
113
115
  warmupFailures.clear();
114
116
  endpointCache.clear();
117
+ toolchainProbeCache.clear();
115
118
  }
116
119
 
117
- export function remoteXpcHidStatus(controllerHome: string, env: NodeJS.ProcessEnv = process.env): Record<string, unknown> {
120
+ const TOOLCHAIN_PROBE_SCRIPT = [
121
+ 'from importlib.metadata import version',
122
+ 'from pymobiledevice3.remote.remote_service_discovery import RemoteServiceDiscoveryService',
123
+ 'from pymobiledevice3.remote.core_device.pasteboard_service import PasteboardService',
124
+ 'from pymobiledevice3.remote.core_device.hid_service import UniversalHIDServiceService, touch_session',
125
+ "print(version('pymobiledevice3'))",
126
+ ].join('; ');
127
+
128
+ function probeHidToolchain(python: string): { installedVersion?: string; available: boolean; reason?: string } {
129
+ const cached = toolchainProbeCache.get(python);
130
+ if (cached && Date.now() - cached.checkedAt <= TOOLCHAIN_PROBE_TTL_MS) return cached;
131
+ const result = spawnSync(python, ['-c', TOOLCHAIN_PROBE_SCRIPT], {
132
+ encoding: 'utf8', timeout: TOOLCHAIN_PROBE_TIMEOUT_MS, maxBuffer: 8 * 1024,
133
+ stdio: ['ignore', 'pipe', 'pipe'],
134
+ });
135
+ const installedVersion = typeof result.stdout === 'string' ? result.stdout.trim() : undefined;
136
+ const available = result.status === 0 && installedVersion === IOS_HID_TOOLCHAIN_VERSION && !result.error;
137
+ const reason = available ? undefined : result.error?.message ?? (result.status === 0
138
+ ? `Expected pymobiledevice3 ${IOS_HID_TOOLCHAIN_VERSION}, found ${installedVersion || 'unknown'}.`
139
+ : `pymobiledevice3 import/version probe failed (exit ${result.status ?? 'unknown'}).`);
140
+ const probe = { checkedAt: Date.now(), installedVersion, available, reason };
141
+ // A failed probe is not durable: an explicitly authorized installer may
142
+ // finish immediately afterward without requiring a Runtime restart.
143
+ if (available) toolchainProbeCache.set(python, probe);
144
+ else toolchainProbeCache.delete(python);
145
+ return probe;
146
+ }
147
+
148
+ function hidToolchainStatus(controllerHome: string, env: NodeJS.ProcessEnv, allowProbe: boolean): Record<string, unknown> {
118
149
  const python = resolvePython(controllerHome, env);
150
+ const cached = python ? toolchainProbeCache.get(python) : undefined;
151
+ const validCached = cached?.available === true && Date.now() - cached.checkedAt <= TOOLCHAIN_PROBE_TTL_MS
152
+ ? cached : undefined;
153
+ const probe = python ? (allowProbe ? probeHidToolchain(python) : validCached) : undefined;
119
154
  return {
120
155
  backend: 'remote-xpc-hid',
121
- available: Boolean(python),
156
+ available: probe?.available === true,
122
157
  python,
123
- toolchainVersion: TOOLCHAIN_VERSION,
158
+ toolchainVersion: IOS_HID_TOOLCHAIN_VERSION,
159
+ ...(probe?.installedVersion ? { installedVersion: probe.installedVersion } : {}),
160
+ ...(probe?.reason ? { reason: probe.reason } : {}),
124
161
  transport: 'macos-trusted-coredevice-rsd',
125
162
  runnerOwned: false,
126
163
  };
127
164
  }
128
165
 
166
+ // Manifest reads are passive: only an explicit HID action may start Python.
167
+ // This is a view of the same short-lived successful probe cache, not a second
168
+ // readiness authority or a durable grant.
169
+ export function remoteXpcHidCachedStatus(controllerHome: string, env: NodeJS.ProcessEnv = process.env): Record<string, unknown> {
170
+ return hidToolchainStatus(controllerHome, env, false);
171
+ }
172
+
173
+ export function remoteXpcHidStatus(controllerHome: string, env: NodeJS.ProcessEnv = process.env): Record<string, unknown> {
174
+ return hidToolchainStatus(controllerHome, env, true);
175
+ }
176
+
129
177
  function resolvePython(controllerHome: string, env: NodeJS.ProcessEnv): string | undefined {
130
178
  const explicit = env.FORGE_IOS_HID_PYTHON?.trim();
131
179
  const candidates = [
132
180
  explicit,
133
- join(controllerHome, 'toolchains', `pymobiledevice3-${TOOLCHAIN_VERSION}-py39`, 'bin', 'python'),
134
- join(controllerHome, 'toolchains', `pymobiledevice3-${TOOLCHAIN_VERSION}`, 'bin', 'python'),
181
+ join(controllerHome, 'toolchains', `pymobiledevice3-${IOS_HID_TOOLCHAIN_VERSION}`, 'bin', 'python'),
135
182
  ].filter((value): value is string => Boolean(value));
136
183
  return candidates.find((candidate) => existsSync(candidate));
137
184
  }
@@ -143,6 +190,7 @@ import asyncio
143
190
  import json
144
191
  import sys
145
192
  import time
193
+ from importlib.metadata import version as package_version
146
194
 
147
195
  from pymobiledevice3.remote.remote_service_discovery import RemoteServiceDiscoveryService
148
196
  from pymobiledevice3.remote.core_device.pasteboard_service import PasteboardService
@@ -222,7 +270,11 @@ async def main():
222
270
  parser = argparse.ArgumentParser()
223
271
  parser.add_argument('--host', required=True)
224
272
  parser.add_argument('--port', required=True, type=int)
273
+ parser.add_argument('--expected-version', required=True)
225
274
  args = parser.parse_args()
275
+ actual_version = package_version('pymobiledevice3')
276
+ if actual_version != args.expected_version:
277
+ raise RuntimeError(f'RemoteXPC HID pymobiledevice3 version mismatch: {actual_version} != {args.expected_version}')
226
278
  async with RemoteServiceDiscoveryService((args.host, args.port)) as rsd:
227
279
  async with touch_session(rsd) as hid:
228
280
  connected = await hid.list_connected_services()
@@ -743,11 +795,12 @@ export function stopRemoteXpcHidForDevice(deviceIdentifier: string): Record<stri
743
795
  }
744
796
 
745
797
  function startWorker(input: Pick<RemoteXpcHidInput, 'controllerHome' | 'deviceIdentifier'>, endpoint: RsdEndpoint): WorkerRecord {
746
- const python = resolvePython(input.controllerHome, process.env);
798
+ const status = remoteXpcHidStatus(input.controllerHome);
799
+ const python = status.available === true && typeof status.python === 'string' ? status.python : undefined;
747
800
  if (!python) {
748
- throw new AssistantPluginError('IOS_HID_TOOLCHAIN_MISSING', `The Controller-owned pymobiledevice3 ${TOOLCHAIN_VERSION} toolchain is unavailable.`, {
801
+ throw new AssistantPluginError('IOS_HID_TOOLCHAIN_MISSING', `The Controller-owned pymobiledevice3 ${IOS_HID_TOOLCHAIN_VERSION} toolchain is unavailable or incompatible.`, {
749
802
  retryable: false,
750
- details: { expected: join(input.controllerHome, 'toolchains', `pymobiledevice3-${TOOLCHAIN_VERSION}-py39`, 'bin', 'python') },
803
+ details: { expected: join(input.controllerHome, 'toolchains', `pymobiledevice3-${IOS_HID_TOOLCHAIN_VERSION}`, 'bin', 'python'), reason: status.reason },
751
804
  });
752
805
  }
753
806
  const script = materializeWorker(input.controllerHome);
@@ -756,6 +809,7 @@ function startWorker(input: Pick<RemoteXpcHidInput, 'controllerHome' | 'deviceId
756
809
  '-u', script,
757
810
  '--host', endpoint.host,
758
811
  '--port', String(endpoint.port),
812
+ '--expected-version', IOS_HID_TOOLCHAIN_VERSION,
759
813
  ], {
760
814
  stdio: ['pipe', 'pipe', 'pipe'],
761
815
  env: {
@@ -1089,23 +1143,11 @@ async function waitForMutationWorker(
1089
1143
  }
1090
1144
  const current = workers.get(input.deviceIdentifier);
1091
1145
  const warmup = warmups.get(input.deviceIdentifier);
1092
- const readiness = current
1093
- ? current.ready.then(() => undefined).catch(() => undefined)
1094
- : warmup;
1095
- if (readiness) {
1096
- let timer: NodeJS.Timeout | undefined;
1097
- try {
1098
- await Promise.race([
1099
- readiness,
1100
- new Promise<void>((resolve) => {
1101
- timer = setTimeout(resolve, MUTATION_READY_BUDGET_MS);
1102
- timer.unref?.();
1103
- }),
1104
- ]);
1105
- } finally {
1106
- if (timer) clearTimeout(timer);
1107
- }
1108
- }
1146
+ // Plugin actions use separate managed processes. A detached prewarm cannot
1147
+ // survive its owning action, so the first real mutation must finish its own
1148
+ // endpoint discovery and worker startup rather than time out and retry cold.
1149
+ const readiness = warmup ?? current?.ready.then(() => undefined).catch(() => undefined);
1150
+ if (readiness) await readiness;
1109
1151
  const waitMs = Math.round((performance.now() - startedAt) * 100) / 100;
1110
1152
  const worker = workers.get(input.deviceIdentifier);
1111
1153
  if (!worker || worker.readyState !== 'ready') {
@@ -1115,15 +1157,13 @@ async function waitForMutationWorker(
1115
1157
  }
1116
1158
  throw new AssistantPluginError(
1117
1159
  'IOS_HID_INPUT_NOT_READY',
1118
- `RemoteXPC HID is still warming after the ${MUTATION_READY_BUDGET_MS}ms mutation readiness budget. No input was sent; retry the same action after prewarm completes.`,
1160
+ 'RemoteXPC HID worker did not reach ready state in this action. No input was sent.',
1119
1161
  {
1120
1162
  retryable: true,
1121
1163
  details: {
1122
1164
  deviceIdentifier: input.deviceIdentifier,
1123
1165
  mutationDispatched: false,
1124
1166
  workerReadyWaitMs: waitMs,
1125
- readinessBudgetMs: MUTATION_READY_BUDGET_MS,
1126
- prewarmContinues: warmups.has(input.deviceIdentifier) || worker?.readyState === 'starting',
1127
1167
  },
1128
1168
  },
1129
1169
  );
@@ -33,14 +33,7 @@ import {
33
33
  iosAgentDeviceStatus,
34
34
  isIosAgentDeviceAction,
35
35
  } from './ios-agent-device';
36
- import {
37
- executeIosPhysicalDeviceAction,
38
- iosPhysicalDeviceActions,
39
- iosPhysicalDeviceCapabilities,
40
- iosPhysicalDeviceStatus,
41
- isIosPhysicalDeviceAction,
42
- resolveIosPhysicalDeviceAuthorizationContext,
43
- } from './ios-physical-device';
36
+ import { iosPhysicalDeviceStatus, isIosPhysicalDeviceAction } from './ios-physical-device';
44
37
 
45
38
  const IOS_PLUGIN_ID = 'ios';
46
39
 
@@ -99,26 +92,36 @@ function health(repoRoot: string): AssistantPluginHealth {
99
92
  } as RepositoryRecord);
100
93
  const currentPlatform = iosDevelopmentPlatform();
101
94
  const platformOk = currentPlatform === 'darwin';
102
- const toolingReady = platformOk && Boolean(xcode && 'ready' in xcode && xcode.ready);
95
+ const developmentReady = platformOk && Boolean(xcode && 'ready' in xcode && xcode.ready);
96
+ const physicalDevice = iosPhysicalDeviceStatus();
97
+ const physicalReady = platformOk && physicalDevice.coreDeviceReady;
98
+ const agentDevice = iosAgentDeviceStatus({ repoRoot });
99
+ const semanticReady = agentDevice.available === true;
100
+ const pluginReady = platformOk && (developmentReady || physicalReady || semanticReady);
103
101
  const warnings: string[] = [];
104
- if (!platformOk) warnings.push('iOS plugin requires macOS with Xcode and Simulator.');
105
- if (platformOk && !xcodeSnapshot.probed) warnings.push('Xcode/simctl readiness has not been explicitly probed in this runtime yet.');
106
- else if (platformOk && !toolingReady) warnings.push('Xcode/simctl is not fully ready on this host.');
102
+ if (!platformOk) warnings.push('iOS capabilities require a macOS host.');
103
+ if (platformOk && !developmentReady) warnings.push('Xcode/Simulator development capability is not fully ready on this host.');
104
+ if (platformOk && !physicalReady) warnings.push('CoreDevice physical-iPhone capability is not ready on this host.');
107
105
  if (!discovery.ready) warnings.push('No .xcworkspace/.xcodeproj/Package.swift discovered in this repository yet.');
108
- const status = userFacingStatusFrom(toolingReady, discovery.ready, Boolean(xcode && 'simctlAvailable' in xcode && xcode.simctlAvailable));
106
+ const status = userFacingStatusFrom(developmentReady, discovery.ready, Boolean(xcode && 'simctlAvailable' in xcode && xcode.simctlAvailable), physicalReady);
109
107
  return {
110
- state: !platformOk ? 'disabled' : toolingReady ? 'ready' : 'degraded',
108
+ state: !platformOk ? 'disabled' : pluginReady ? 'ready' : 'degraded',
111
109
  checkedAt: now(),
112
- ready: toolingReady,
113
- probed: xcodeSnapshot.probed,
110
+ ready: pluginReady,
111
+ probed: xcodeSnapshot.probed || physicalDevice.probed || Boolean(agentDevice.available),
114
112
  errors: [],
115
113
  warnings,
116
114
  details: {
117
- provider: 'local-xcode',
115
+ provider: 'local-ios',
118
116
  platform: currentPlatform,
119
117
  userFacingStatus: status,
120
118
  discoverable: discovery.ready,
121
119
  defaultContainer: discovery.defaultContainer,
120
+ capabilities: {
121
+ development: developmentReady,
122
+ physicalDevice: physicalReady,
123
+ semanticAgentDevice: semanticReady,
124
+ },
122
125
  xcode: xcode && 'ready' in xcode ? {
123
126
  ready: xcode.ready,
124
127
  xcodeSelectPath: 'xcodeSelectPath' in xcode ? xcode.xcodeSelectPath : undefined,
@@ -127,8 +130,8 @@ function health(repoRoot: string): AssistantPluginHealth {
127
130
  probed: xcodeSnapshot.probed,
128
131
  cached: xcodeSnapshot.cached,
129
132
  } : xcode,
130
- agentDevice: iosAgentDeviceStatus({ repoRoot }),
131
- physicalDevice: iosPhysicalDeviceStatus(),
133
+ agentDevice,
134
+ physicalDevice,
132
135
  artifactRoots: {
133
136
  repoLocal: '.forge/ios/',
134
137
  controller: 'controller-home/repositories/<repoId>/artifacts/ios/',
@@ -137,21 +140,22 @@ function health(repoRoot: string): AssistantPluginHealth {
137
140
  };
138
141
  }
139
142
 
140
- function userFacingStatusFrom(toolingReady: boolean, discoverable: boolean, simReady: boolean): string {
141
- if (!toolingReady && !discoverable) return 'not_configured';
142
- if (discoverable && toolingReady && simReady) return 'buildable';
143
+ function userFacingStatusFrom(toolingReady: boolean, discoverable: boolean, simReady: boolean, physicalReady: boolean): string {
144
+ if (!toolingReady && !physicalReady && !discoverable) return 'not_configured';
145
+ if (toolingReady && discoverable && simReady) return 'buildable';
146
+ if (physicalReady && !toolingReady) return 'physical_device_ready';
143
147
  if (toolingReady && simReady) return 'simulator_ready';
144
148
  if (discoverable) return 'discoverable';
145
- if (toolingReady) return 'simulator_ready';
149
+ if (physicalReady) return 'physical_device_ready';
146
150
  return 'not_configured';
147
151
  }
148
152
 
149
- function permissions(ready: boolean): AssistantPluginPermissionScope[] {
153
+ function permissions(input: { developmentReady: boolean; physicalReady: boolean }): AssistantPluginPermissionScope[] {
150
154
  return [
151
- { scope: 'ios.discover', mode: 'read', description: 'Discover Xcode projects, schemes, and simulator inventory.', granted: ready, required: true },
152
- { scope: 'ios.build', mode: 'write', description: 'Build iOS app targets into bounded DerivedData.', granted: ready, required: true },
153
- { scope: 'ios.simulator', mode: 'write', description: 'Boot simulators, install, launch, screenshot, and collect logs.', granted: ready, required: true },
154
- { scope: 'ios.device', mode: 'write', description: 'Inspect and operate an exact paired physical iPhone through CoreDevice; optional XCTest semantics are isolated in the agent-device fallback.', granted: ready, required: false },
155
+ { scope: 'ios.discover', mode: 'read', description: 'Discover iOS projects and paired physical devices.', granted: input.developmentReady || input.physicalReady, required: true },
156
+ { scope: 'ios.build', mode: 'write', description: 'Build iOS app targets into bounded DerivedData.', granted: input.developmentReady, required: true },
157
+ { scope: 'ios.simulator', mode: 'write', description: 'Boot simulators, install, launch, screenshot, and collect logs.', granted: input.developmentReady, required: true },
158
+ { scope: 'ios.device', mode: 'write', description: 'Explicit paired-iPhone development/XCTest actions; everyday CoreDevice app interaction belongs to Computer.', granted: input.physicalReady, required: false },
155
159
  ];
156
160
  }
157
161
 
@@ -172,7 +176,6 @@ function capabilities(): AssistantPluginCapability[] {
172
176
  actions: ['smoke_review', 'build', 'xcode_test', 'launch_simulator', 'capture_screenshot'],
173
177
  },
174
178
  ...iosAgentDeviceCapabilities(),
175
- ...iosPhysicalDeviceCapabilities(),
176
179
  ];
177
180
  }
178
181
 
@@ -345,7 +348,7 @@ function actions(): AssistantPluginActionDescriptor[] {
345
348
  description: 'Capture a simulator screenshot into controller artifact storage.',
346
349
  readOnly: false,
347
350
  risk: 'workspace_write',
348
- confirmation: 'none',
351
+ confirmation: 'authorization',
349
352
  defaultTimeoutMs: 60_000,
350
353
  cancellable: true,
351
354
  idempotent: false,
@@ -395,7 +398,6 @@ function actions(): AssistantPluginActionDescriptor[] {
395
398
  },
396
399
  },
397
400
  ...iosAgentDeviceActions(),
398
- ...iosPhysicalDeviceActions(),
399
401
  ];
400
402
  }
401
403
 
@@ -408,7 +410,7 @@ export function buildIosPluginManifest(previousRevision = 0, previousUpdatedAt?:
408
410
  revision: Math.max(1, previousRevision || 1),
409
411
  pluginId: IOS_PLUGIN_ID,
410
412
  provider: 'apple-local',
411
- displayName: 'iOS Development Plugin',
413
+ displayName: 'iOS Development / Simulator / XCTest',
412
414
  pluginVersion: '1.0.0',
413
415
  authority: {
414
416
  strategy: 'derived',
@@ -419,13 +421,16 @@ export function buildIosPluginManifest(previousRevision = 0, previousUpdatedAt?:
419
421
  lifecycle: {
420
422
  state: !enabled ? 'disabled' : state.ready ? 'enabled' : 'degraded',
421
423
  reason: !enabled
422
- ? 'iOS plugin is only available on macOS hosts.'
424
+ ? 'iOS capabilities are only available on macOS hosts.'
423
425
  : state.ready
424
- ? 'Xcode and Simulator tooling are ready.'
425
- : state.warnings[0] ?? 'iOS tooling is partially available.',
426
+ ? 'At least one iOS development or physical-device capability is ready.'
427
+ : state.warnings[0] ?? 'iOS capabilities are partially available.',
426
428
  },
427
429
  health: state,
428
- permissions: permissions(state.ready),
430
+ permissions: permissions({
431
+ developmentReady: Boolean(state.details?.capabilities && typeof state.details.capabilities === 'object' && (state.details.capabilities as Record<string, unknown>).development === true),
432
+ physicalReady: Boolean(state.details?.capabilities && typeof state.details.capabilities === 'object' && (state.details.capabilities as Record<string, unknown>).physicalDevice === true),
433
+ }),
429
434
  capabilities: capabilities(),
430
435
  actions: actions(),
431
436
  updatedAt: previousUpdatedAt ?? now(),
@@ -434,7 +439,9 @@ export function buildIosPluginManifest(previousRevision = 0, previousUpdatedAt?:
434
439
 
435
440
  export async function executeIosPluginAction(input: AssistantPluginActionExecutionInput): Promise<Record<string, unknown>> {
436
441
  if (isIosAgentDeviceAction(input.actionId)) return executeIosAgentDeviceAction(input);
437
- if (isIosPhysicalDeviceAction(input.actionId)) return executeIosPhysicalDeviceAction(input);
442
+ if (isIosPhysicalDeviceAction(input.actionId)) {
443
+ throw new AssistantPluginError('PLUGIN_ACTION_NOT_SUPPORTED', `Physical iPhone app actions are available only through computer/${input.actionId}.`, { retryable: false });
444
+ }
438
445
  const currentPlatform = iosDevelopmentPlatform();
439
446
  if (currentPlatform !== 'darwin' && input.actionId !== 'discover_project' && input.actionId !== 'xcode_status') {
440
447
  throw new AssistantPluginError('PLUGIN_DEPENDENCY_MISSING', 'iOS plugin actions require macOS with Xcode/Simulator.', {
@@ -590,9 +597,7 @@ export async function executeIosPluginAction(input: AssistantPluginActionExecuti
590
597
  export const iosPluginAdapter = {
591
598
  pluginId: IOS_PLUGIN_ID,
592
599
  buildManifest: buildIosPluginManifest,
593
- resolveAuthorizationContext: async (input: AssistantPluginActionExecutionInput) => {
594
- if (!isIosPhysicalDeviceAction(input.actionId)) return undefined;
595
- return resolveIosPhysicalDeviceAuthorizationContext(input);
596
- },
600
+ // CoreDevice actions are public only through the Computer manifest; Xcode and XCTest stay here.
601
+ resolveAuthorizationContext: async () => undefined,
597
602
  executeAction: executeIosPluginAction,
598
603
  };
@@ -8,6 +8,7 @@ import { runBoundedProcess } from '../execution/thin-harness/async-process';
8
8
  import { readJsonFile, writeJsonAtomic } from '../shared/json-files';
9
9
  import { resolveTrustedNodeExecutable } from '../shared/trusted-node-executable';
10
10
  import { AssistantPluginError, toAssistantPluginError } from './errors';
11
+ import { ensureIosDeviceOwnership, releaseIosDeviceOwnership, withIosDeviceTransientOwnership } from './ios-device-ownership';
11
12
  import {
12
13
  interactionAutomationEngine,
13
14
  interactionMayOwnTarget,
@@ -734,6 +735,15 @@ function providerForDevice(device: AgentDeviceEntry): InteractionProvider {
734
735
  return device.kind === 'simulator' ? SIMULATOR_PROVIDER : DEVICE_PROVIDER;
735
736
  }
736
737
 
738
+ async function runPhysicalDeviceCommand<T>(
739
+ input: AssistantPluginActionExecutionInput,
740
+ device: AgentDeviceEntry,
741
+ operation: () => Promise<T>,
742
+ ): Promise<T> {
743
+ if (device.kind !== 'device') return operation();
744
+ return withIosDeviceTransientOwnership(input.controllerHome, input.repoId, input.requestId, device.id, operation);
745
+ }
746
+
737
747
  function selectTarget(input: AssistantPluginActionExecutionInput, selector?: string): AgentDeviceEntry {
738
748
  const inventory = devices(input);
739
749
  const normalizedSelector = selector?.trim().toLocaleLowerCase('en-US');
@@ -835,12 +845,26 @@ function requireRecord(input: AssistantPluginActionExecutionInput, allowTerminal
835
845
  status: 'closing',
836
846
  error: { code: 'AGENT_DEVICE_CLEANUP_FAILED', message: 'The expired agent-device session could not be closed; ownership remains fenced.' },
837
847
  });
848
+ if (record.provider === DEVICE_PROVIDER && closed) releaseIosDeviceOwnership(input.controllerHome, record.owner.repoId, interactionId, record.targetId);
838
849
  throw new AssistantPluginError(
839
850
  closed ? 'AGENT_DEVICE_SESSION_EXPIRED' : 'AGENT_DEVICE_CLEANUP_FAILED',
840
851
  closed ? 'The agent-device session expired and was closed.' : 'The expired agent-device session could not be closed; retry agent_device_close.',
841
852
  { retryable: !closed },
842
853
  );
843
854
  }
855
+ if (record.provider === DEVICE_PROVIDER) {
856
+ const ownership = ensureIosDeviceOwnership(input.controllerHome, input.repoId, interactionId, record.targetId);
857
+ if (!ownership.acquired) {
858
+ throw new AssistantPluginError('PLUGIN_RESOURCE_BUSY', 'The selected iPhone is already owned by another active Forge interaction.', {
859
+ retryable: true,
860
+ details: { interactionId, targetId: record.targetId, blocker: ownership.blocker },
861
+ });
862
+ }
863
+ const active = patchInteractionSession(input.repoRoot, record.provider, interactionId, {
864
+ expiresAt: new Date(hooks.now().getTime() + SESSION_EXPIRY_MS).toISOString(),
865
+ });
866
+ if (active) return active;
867
+ }
844
868
  return record;
845
869
  }
846
870
 
@@ -915,6 +939,7 @@ function reconcileExpiredSessions(input: AssistantPluginActionExecutionInput): v
915
939
  status: 'closing',
916
940
  error: { code: 'AGENT_DEVICE_CLEANUP_FAILED', message: 'The expired agent-device session could not be closed; ownership remains fenced.' },
917
941
  });
942
+ if (record.provider === DEVICE_PROVIDER && closed) releaseIosDeviceOwnership(input.controllerHome, record.owner.repoId, record.interactionId, record.targetId);
918
943
  }
919
944
  }
920
945
 
@@ -934,6 +959,7 @@ function failSession(input: AssistantPluginActionExecutionInput, record: Interac
934
959
  status: 'closing',
935
960
  error: { code: 'AGENT_DEVICE_CLEANUP_FAILED', message: `${normalized.message}; cleanup failed and ownership remains fenced.` },
936
961
  });
962
+ if (closed && record.provider === DEVICE_PROVIDER) releaseIosDeviceOwnership(input.controllerHome, record.owner.repoId, record.interactionId, record.targetId);
937
963
  if (!closed) {
938
964
  throw new AssistantPluginError('AGENT_DEVICE_CLEANUP_FAILED', 'The agent-device action failed and its session could not be closed; retry agent_device_close.', {
939
965
  retryable: true,
@@ -2258,12 +2284,12 @@ export async function executeIosAgentDeviceAction(input: AssistantPluginActionEx
2258
2284
  contractFingerprint: dependency.capabilityProfile.contractFingerprint,
2259
2285
  device: selected,
2260
2286
  physicalDeviceSupported: selected.kind === 'device',
2261
- result: bounded(await runJsonAsync(input, args, {
2287
+ result: bounded(await runPhysicalDeviceCommand(input, selected, () => runJsonAsync(input, args, {
2262
2288
  signing: signingFromArgs(input.args),
2263
2289
  stateDir: targetRuntimeStateDir(input, selected),
2264
2290
  failureCode: 'AGENT_DEVICE_DOCTOR_FAILED',
2265
2291
  timeoutMs: 4 * 60_000,
2266
- })),
2292
+ }))),
2267
2293
  };
2268
2294
  }
2269
2295
 
@@ -2276,14 +2302,14 @@ export async function executeIosAgentDeviceAction(input: AssistantPluginActionEx
2276
2302
  contractFingerprint: dependency.capabilityProfile.contractFingerprint,
2277
2303
  device: selected,
2278
2304
  physicalDeviceSupported: selected.kind === 'device',
2279
- result: bounded(await runJsonAsync(input, [
2305
+ result: bounded(await runPhysicalDeviceCommand(input, selected, () => runJsonAsync(input, [
2280
2306
  'prepare', 'ios-runner', '--platform', 'ios', '--device', selected.name, '--timeout', '600000', '--json',
2281
2307
  ], {
2282
2308
  signing,
2283
2309
  stateDir: targetRuntimeStateDir(input, selected),
2284
2310
  failureCode: 'AGENT_DEVICE_PREPARE_FAILED',
2285
2311
  timeoutMs: 10 * 60_000,
2286
- })),
2312
+ }))),
2287
2313
  };
2288
2314
  }
2289
2315
 
@@ -2298,6 +2324,19 @@ export async function executeIosAgentDeviceAction(input: AssistantPluginActionEx
2298
2324
  const conflict = listInteractionSessions(input.repoRoot, provider).find((entry) =>
2299
2325
  isInteractionSessionActive(entry.status) && interactionMayOwnTarget(entry, selected.aliases));
2300
2326
  if (conflict) {
2327
+ if (selected.kind === 'device' && provider === DEVICE_PROVIDER && conflict.instructions === app && input.args.relaunch !== true) {
2328
+ const ownership = ensureIosDeviceOwnership(input.controllerHome, input.repoId, conflict.interactionId, selected.id);
2329
+ if (!ownership.acquired) {
2330
+ throw new AssistantPluginError('PLUGIN_RESOURCE_BUSY', 'The selected iPhone is already owned by another active Forge interaction.', {
2331
+ retryable: true,
2332
+ details: { interactionId: conflict.interactionId, targetId: conflict.targetId, blocker: ownership.blocker },
2333
+ });
2334
+ }
2335
+ const active = patchInteractionSession(input.repoRoot, provider, conflict.interactionId, {
2336
+ expiresAt: new Date(hooks.now().getTime() + SESSION_EXPIRY_MS).toISOString(),
2337
+ }) ?? conflict;
2338
+ return { provider: 'agent-device', version: dependency.detectedVersion ?? IOS_AGENT_DEVICE_VERSION, contractFingerprint: dependency.capabilityProfile.contractFingerprint, interaction: active, device: selected, physicalDeviceSupported: true, reusedSession: true };
2339
+ }
2301
2340
  throw new AssistantPluginError('PLUGIN_RESOURCE_BUSY', 'The selected iOS target already has an active interaction.', {
2302
2341
  retryable: true,
2303
2342
  details: {
@@ -2310,6 +2349,15 @@ export async function executeIosAgentDeviceAction(input: AssistantPluginActionEx
2310
2349
  }
2311
2350
  pruneInteractionSessions(input.repoRoot, provider, 100);
2312
2351
  const interactionId = `ios_agent_device_${randomUUID()}`;
2352
+ if (selected.kind === 'device') {
2353
+ const ownership = ensureIosDeviceOwnership(input.controllerHome, input.repoId, interactionId, selected.id);
2354
+ if (!ownership.acquired) {
2355
+ throw new AssistantPluginError('PLUGIN_RESOURCE_BUSY', 'The selected iPhone is already owned by another active Forge interaction.', {
2356
+ retryable: true,
2357
+ details: { interactionId, targetId: selected.id, blocker: ownership.blocker },
2358
+ });
2359
+ }
2360
+ }
2313
2361
  const createdAt = timestamp();
2314
2362
  const record: InteractionSessionRecord = {
2315
2363
  schemaVersion: 1,
@@ -2348,6 +2396,7 @@ export async function executeIosAgentDeviceAction(input: AssistantPluginActionEx
2348
2396
  result: bounded(result),
2349
2397
  };
2350
2398
  } catch (error) {
2399
+ if (selected.kind === 'device') releaseIosDeviceOwnership(input.controllerHome, input.repoId, interactionId, selected.id);
2351
2400
  return failSession(input, record, error);
2352
2401
  }
2353
2402
  }
@@ -2464,6 +2513,7 @@ export async function executeIosAgentDeviceAction(input: AssistantPluginActionEx
2464
2513
  try {
2465
2514
  const closedProvider = await closeProviderSession(input, current, args);
2466
2515
  const closed = patchInteractionSession(input.repoRoot, current.provider, current.interactionId, { status: 'closed' }) ?? current;
2516
+ if (current.provider === DEVICE_PROVIDER) releaseIosDeviceOwnership(input.controllerHome, current.owner.repoId, current.interactionId, current.targetId);
2467
2517
  return {
2468
2518
  provider: 'agent-device',
2469
2519
  interaction: closed,
@@ -0,0 +1,103 @@
1
+ import {
2
+ acquireControllerLock,
3
+ ControllerLockContentionError,
4
+ readControllerLock,
5
+ releaseControllerLock,
6
+ renewControllerLock,
7
+ type ControllerLockRecord,
8
+ } from '../../cli/repositories/locks';
9
+
10
+ const IOS_DEVICE_LOCK_PREFIX = 'ios-device:';
11
+ const IOS_DEVICE_LOCK_TTL_MS = 2 * 60 * 60_000;
12
+
13
+ export interface IosDeviceOwnershipResult {
14
+ acquired: boolean;
15
+ lock?: ControllerLockRecord;
16
+ blocker?: Pick<ControllerLockRecord, 'lockId' | 'owner' | 'pid' | 'acquiredAt' | 'heartbeatAt' | 'expiresAt'>;
17
+ }
18
+
19
+ function deviceResourceKey(deviceIdentifier: string): string {
20
+ const normalized = deviceIdentifier.trim().toUpperCase();
21
+ if (!normalized) throw new Error('IOS_DEVICE_IDENTIFIER_REQUIRED');
22
+ return `${IOS_DEVICE_LOCK_PREFIX}${normalized}`;
23
+ }
24
+
25
+ function sessionOwner(repoId: string, interactionId: string): string {
26
+ const repo = repoId.trim();
27
+ const interaction = interactionId.trim();
28
+ if (!repo || !interaction) throw new Error('IOS_DEVICE_OWNERSHIP_ID_REQUIRED');
29
+ return `ios-device-session:${repo}:${interaction}`;
30
+ }
31
+
32
+ function blocker(lock: ControllerLockRecord) {
33
+ return {
34
+ lockId: lock.lockId,
35
+ owner: lock.owner,
36
+ pid: lock.pid,
37
+ acquiredAt: lock.acquiredAt,
38
+ heartbeatAt: lock.heartbeatAt,
39
+ ...(lock.expiresAt ? { expiresAt: lock.expiresAt } : {}),
40
+ } satisfies IosDeviceOwnershipResult['blocker'];
41
+ }
42
+
43
+ // Use the hardware UDID as the single physical iPhone identity shared with XCTest.
44
+ // CoreDevice identifier is a transport-local locator, not the agent-device device id.
45
+ export function iosCoreDeviceOwnershipId(device: { identifier: string; udid?: string }): string {
46
+ const udid = device.udid?.trim();
47
+ if (!udid) throw new Error('IOS_DEVICE_UDID_REQUIRED');
48
+ return udid;
49
+ }
50
+
51
+ export function ensureIosDeviceOwnership(
52
+ controllerHome: string,
53
+ repoId: string,
54
+ interactionId: string,
55
+ deviceIdentifier: string,
56
+ ): IosDeviceOwnershipResult {
57
+ const key = { scope: 'global' as const, resource: deviceResourceKey(deviceIdentifier) };
58
+ const owner = sessionOwner(repoId, interactionId);
59
+ const current = readControllerLock(controllerHome, key);
60
+ if (current) {
61
+ if (current.owner !== owner) return { acquired: false, blocker: blocker(current) };
62
+ return { acquired: true, lock: renewControllerLock(controllerHome, key, current.lockId, IOS_DEVICE_LOCK_TTL_MS) };
63
+ }
64
+ try {
65
+ return { acquired: true, lock: acquireControllerLock(controllerHome, key, owner, IOS_DEVICE_LOCK_TTL_MS) };
66
+ } catch (error) {
67
+ if (!(error instanceof ControllerLockContentionError)) throw error;
68
+ const raced = readControllerLock(controllerHome, key);
69
+ if (!raced) return { acquired: false };
70
+ if (raced.owner !== owner) return { acquired: false, blocker: blocker(raced) };
71
+ return { acquired: true, lock: renewControllerLock(controllerHome, key, raced.lockId, IOS_DEVICE_LOCK_TTL_MS) };
72
+ }
73
+ }
74
+
75
+ export function releaseIosDeviceOwnership(
76
+ controllerHome: string,
77
+ repoId: string,
78
+ interactionId: string,
79
+ deviceIdentifier: string,
80
+ ): boolean {
81
+ const key = { scope: 'global' as const, resource: deviceResourceKey(deviceIdentifier) };
82
+ const current = readControllerLock(controllerHome, key);
83
+ if (!current || current.owner !== sessionOwner(repoId, interactionId)) return false;
84
+ releaseControllerLock(controllerHome, key, current.lockId);
85
+ return true;
86
+ }
87
+
88
+ export async function withIosDeviceTransientOwnership<T>(
89
+ controllerHome: string,
90
+ repoId: string,
91
+ requestId: string,
92
+ deviceIdentifier: string,
93
+ operation: () => T | Promise<T>,
94
+ ): Promise<T> {
95
+ const key = { scope: 'global' as const, resource: deviceResourceKey(deviceIdentifier) };
96
+ const owner = `ios-device-transient:${repoId}:${requestId}`;
97
+ const lock = acquireControllerLock(controllerHome, key, owner, undefined);
98
+ try {
99
+ return await operation();
100
+ } finally {
101
+ releaseControllerLock(controllerHome, key, lock.lockId);
102
+ }
103
+ }