@moretea-labs/forge 1.7.2 → 1.8.0

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 (685) hide show
  1. package/AGENTS.md +58 -62
  2. package/CHANGELOG.md +26 -0
  3. package/CLAUDE.md +42 -62
  4. package/README.md +2 -2
  5. package/SKILL.md +0 -1
  6. package/THIRD_PARTY_NOTICES.md +5 -2
  7. package/adapters/browser/index.ts +2 -0
  8. package/adapters/chatgpt/browser-delivery-host.ts +71 -0
  9. package/adapters/chatgpt/browser-delivery-runtime.ts +783 -0
  10. package/adapters/chatgpt/controller-binding-store.ts +55 -0
  11. package/adapters/chatgpt/controller-host.ts +119 -0
  12. package/adapters/chatgpt/controller-round-host.ts +78 -0
  13. package/adapters/chatgpt/controller-round-settlement-store.ts +45 -0
  14. package/adapters/chatgpt/provider-delivery.ts +113 -0
  15. package/adapters/chatgpt/work-conversation-binding-store.ts +192 -0
  16. package/adapters/chatgpt/wsl-bridge-delivery-host.ts +63 -0
  17. package/adapters/computer/desktop-operator-contract.ts +7 -0
  18. package/adapters/computer/desktop-operator-discovery.ts +201 -0
  19. package/adapters/computer/desktop-operator-negotiation.ts +174 -0
  20. package/adapters/computer/desktop-operator-provider.ts +312 -0
  21. package/adapters/computer/index.ts +1 -0
  22. package/adapters/computer/interaction-target-authority.ts +944 -0
  23. package/adapters/controller-process/binding-store.ts +34 -0
  24. package/adapters/controller-process/controller-host.ts +26 -0
  25. package/adapters/mcp/access-mode.ts +132 -0
  26. package/adapters/mcp/audit.ts +32 -0
  27. package/adapters/mcp/auth.ts +407 -0
  28. package/adapters/mcp/controller-round-compatibility.ts +184 -0
  29. package/adapters/mcp/frozen-client-semantic-compatibility.ts +292 -0
  30. package/adapters/mcp/instructions.ts +36 -0
  31. package/adapters/mcp/legacy-context.ts +18 -0
  32. package/adapters/mcp/multi-repository.ts +437 -0
  33. package/adapters/mcp/oauth.ts +391 -0
  34. package/adapters/mcp/paths.ts +140 -0
  35. package/adapters/mcp/policy.ts +232 -0
  36. package/adapters/mcp/proxy-env.ts +62 -0
  37. package/adapters/mcp/readiness-projection.ts +24 -0
  38. package/adapters/mcp/redaction.ts +21 -0
  39. package/adapters/mcp/repo.ts +24 -0
  40. package/adapters/mcp/runtime-gateway/artifact-adapter.ts +52 -0
  41. package/adapters/mcp/runtime-gateway/context-adapter.ts +829 -0
  42. package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +191 -0
  43. package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +147 -0
  44. package/adapters/mcp/runtime-gateway/execution-control-adapter.ts +28 -0
  45. package/adapters/mcp/runtime-gateway/execution-tools.ts +207 -0
  46. package/adapters/mcp/runtime-gateway/filesystem-adapter.ts +38 -0
  47. package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +411 -0
  48. package/adapters/mcp/runtime-gateway/legacy-ios-tool-adapter.ts +105 -0
  49. package/adapters/mcp/runtime-gateway/maintenance-adapter.ts +44 -0
  50. package/adapters/mcp/runtime-gateway/model-adapter.ts +63 -0
  51. package/adapters/mcp/runtime-gateway/persisted-check-process.ts +3 -0
  52. package/adapters/mcp/runtime-gateway/plugin-adapter.ts +308 -0
  53. package/adapters/mcp/runtime-gateway/process-tools.ts +289 -0
  54. package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +76 -0
  55. package/adapters/mcp/runtime-gateway/recovery-adapter.ts +268 -0
  56. package/adapters/mcp/runtime-gateway/recovery-client-adapter.ts +70 -0
  57. package/adapters/mcp/runtime-gateway/recovery-tool-contract.ts +99 -0
  58. package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +110 -0
  59. package/adapters/mcp/runtime-gateway/result-adapter.ts +108 -0
  60. package/adapters/mcp/runtime-gateway/router.ts +728 -0
  61. package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +1251 -0
  62. package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +634 -0
  63. package/adapters/mcp/runtime-gateway/runtime-tool-shared.ts +27 -0
  64. package/adapters/mcp/runtime-gateway/runtime-tools.ts +68 -0
  65. package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +186 -0
  66. package/adapters/mcp/runtime-gateway/shared-adapter.ts +25 -0
  67. package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +870 -0
  68. package/adapters/mcp/runtime-gateway/work-adapter.ts +3186 -0
  69. package/adapters/mcp/runtime-gateway/work-compat-adapter.ts +502 -0
  70. package/adapters/mcp/runtime-gateway/work-validation-reconciler.ts +1 -0
  71. package/adapters/mcp/server.ts +1048 -0
  72. package/adapters/mcp/setup.ts +791 -0
  73. package/adapters/mcp/tool-capability-cache.ts +87 -0
  74. package/adapters/mcp/tool-mapping/access-tools.ts +387 -0
  75. package/adapters/mcp/tool-mapping/legacy-tool-service.ts +5265 -0
  76. package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +150 -0
  77. package/adapters/mcp/tool-mapping/repository-tools.ts +1691 -0
  78. package/adapters/mcp/tool-mapping/tools.ts +9 -0
  79. package/adapters/mcp/tool-mapping/umbrella-tools.ts +117 -0
  80. package/adapters/mcp/toolset-names.ts +74 -0
  81. package/adapters/mcp/toolset-selection.ts +41 -0
  82. package/adapters/mcp/toolset.ts +336 -0
  83. package/adapters/mcp/transports/http.ts +1456 -0
  84. package/adapters/mcp/transports/session-registry.ts +513 -0
  85. package/adapters/mcp/transports/stdio.ts +8 -0
  86. package/adapters/mcp/tunnels/openai-secure-tunnel.ts +139 -0
  87. package/adapters/mcp/types.ts +41 -0
  88. package/assets/AGENTS.md +2 -16
  89. package/assets/CLAUDE.md +2 -16
  90. package/assets/hooks/AGENTS.md +3 -14
  91. package/assets/hooks/CLAUDE.md +3 -14
  92. package/assets/hooks/hook-input.sh +9 -2
  93. package/assets/hooks/lib/workflow-state.sh +28 -10
  94. package/assets/hooks/prompt-guard.sh +63 -37
  95. package/assets/hooks/security-sentinel.sh +2 -1
  96. package/assets/hooks/session-start-context.sh +7 -5
  97. package/assets/hooks/stop-orchestrator.sh +13 -3
  98. package/assets/initializer-question-pack.v4.json +11 -7
  99. package/assets/partials/05-workflow.partial.md +18 -73
  100. package/assets/partials/07-footer.partial.md +1 -1
  101. package/assets/partials-agents/02-operating-mode.partial.md +1 -2
  102. package/assets/partials-agents/04-task-protocol.partial.md +14 -59
  103. package/assets/partials-agents/06-quality-safety.partial.md +11 -16
  104. package/assets/partials-agents/08-deep-docs.partial.md +1 -2
  105. package/assets/plan-map.json +11 -11
  106. package/assets/plugin-registry.v1.json +9 -3
  107. package/assets/plugin-trust-policy.v1.json +6 -0
  108. package/assets/recovery/ForgeRecovery.ps1 +100 -0
  109. package/assets/recovery/forge-wsl-rescue +271 -0
  110. package/assets/reference-configs/development-protocol.md +11 -15
  111. package/assets/reference-configs/document-generation.md +1 -1
  112. package/assets/reference-configs/global-working-rules.md +9 -1
  113. package/assets/reference-configs/harness-overview.md +22 -112
  114. package/assets/reference-configs/hook-operations.md +1 -1
  115. package/assets/reference-configs/sprint-contracts.md +2 -2
  116. package/assets/skill-version.json +2 -2
  117. package/assets/templates/helpers/architecture-event.ts +3 -34
  118. package/assets/templates/helpers/architecture-queue.sh +61 -10
  119. package/assets/templates/helpers/archive-workflow.sh +90 -180
  120. package/assets/templates/helpers/capability-config.ts +8 -11
  121. package/assets/templates/helpers/capability-resolver.ts +37 -19
  122. package/assets/templates/helpers/capture-plan.sh +2 -2
  123. package/assets/templates/helpers/check-architecture-sync.sh +1 -9
  124. package/assets/templates/helpers/check-task-sync.sh +82 -11
  125. package/assets/templates/helpers/check-task-workflow.sh +1 -3
  126. package/assets/templates/helpers/context-contract-sync.sh +1 -12
  127. package/assets/templates/helpers/contract-worktree.sh +26 -24
  128. package/assets/templates/helpers/ensure-task-workflow.sh +6 -8
  129. package/assets/templates/helpers/inspect-project-state.ts +1 -1
  130. package/assets/templates/helpers/migrate-project-template.sh +1 -1
  131. package/assets/templates/helpers/migrate-workflow-docs.ts +53 -239
  132. package/assets/templates/helpers/new-plan.sh +2 -2
  133. package/assets/templates/helpers/plan-to-todo.sh +3 -31
  134. package/assets/templates/helpers/sprint-backlog.sh +1 -1
  135. package/assets/templates/helpers/switch-plan.sh +1 -1
  136. package/assets/templates/helpers/workflow-contract.ts +1 -0
  137. package/assets/workflow-contract.v1.json +63 -171
  138. package/assets/workflows/xiaohongshu/xiaohongshu.collect-metrics.v1.draft.json +118 -0
  139. package/assets/workflows/xiaohongshu/xiaohongshu.publish-image-note.v1.draft.json +316 -0
  140. package/assets/workflows/xiaohongshu/xiaohongshu.publish-long-text.v1.draft.json +324 -0
  141. package/docs/architecture/CURRENT.md +148 -13
  142. package/docs/architecture/EVOLUTION.md +13 -0
  143. package/docs/architecture/decisions/20260801-controller-home-sqlite-state.md +2 -1
  144. package/docs/architecture/decisions/20260831-independent-windows-wsl-host-rescue.md +59 -0
  145. package/docs/architecture/decisions/20260904-ios-device-migration-baseline.md +120 -0
  146. package/docs/architecture/decisions/20260904-repository-runtime-data-boundary.md +42 -0
  147. package/docs/architecture/decisions/20260907-assistant-learning-loop.md +35 -0
  148. package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +296 -0
  149. package/docs/architecture/decisions/20260907-maintenance-diagnosis-bounded-read.md +39 -0
  150. package/docs/architecture/domains/verification.md +7 -0
  151. package/docs/architecture/domains/workflow-engine.md +1 -1
  152. package/docs/architecture/index.md +3 -3
  153. package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +19 -8
  154. package/docs/architecture/requests/2026-09-04-computer-plugin-workflow-taxonomy.md +124 -0
  155. package/docs/forge-chatgpt-mcp-setup.md +5 -3
  156. package/docs/forge-plugin-management.md +20 -4
  157. package/docs/forge-runtime-self-healing-loop.md +2 -0
  158. package/docs/operations/benchmark-cross-version-freeze.md +38 -0
  159. package/docs/operations/controller-browser-plugin.md +3 -1
  160. package/docs/operations/homebrew.md +2 -2
  161. package/docs/operations/platform-support.md +16 -8
  162. package/docs/operations/platform-support.zh-CN.md +2 -2
  163. package/docs/operations/standalone-disaster-recovery.md +26 -1
  164. package/docs/operations/uu-remote-rescue.md +41 -0
  165. package/docs/operations/windows-wsl-host-rescue.md +133 -0
  166. package/docs/public-usage-guide.md +1 -1
  167. package/docs/public-usage-guide.zh-CN.md +1 -1
  168. package/docs/tutorials/01-install-and-start.md +1 -1
  169. package/docs/tutorials/01-install-and-start.zh-CN.md +1 -1
  170. package/docs/tutorials/02-connect-chatgpt.md +4 -4
  171. package/docs/tutorials/02-connect-chatgpt.zh-CN.md +4 -4
  172. package/docs/wiki/Implementation.md +1 -1
  173. package/package.json +23 -14
  174. package/packages/kernel/controller/api/index.ts +2 -0
  175. package/packages/kernel/controller/application/controller-round-service.ts +29 -0
  176. package/packages/kernel/controller/application/controller-service.ts +30 -0
  177. package/packages/kernel/controller/domain/controller-round-transition-policy.ts +308 -0
  178. package/packages/kernel/controller/domain/controller-round.ts +107 -0
  179. package/packages/kernel/controller/domain/execution-quality.ts +133 -0
  180. package/packages/kernel/controller/domain/types.ts +56 -0
  181. package/packages/kernel/controller/index.ts +1 -0
  182. package/packages/kernel/controller/infrastructure/controller-binding-store.ts +84 -0
  183. package/packages/kernel/controller/infrastructure/controller-round-store.ts +1384 -0
  184. package/packages/kernel/controller/infrastructure/controller-session-store.ts +578 -0
  185. package/packages/kernel/controller/ports/controller-host.ts +16 -0
  186. package/packages/kernel/goal/api/index.ts +1 -0
  187. package/packages/kernel/goal/domain/types.ts +40 -0
  188. package/packages/kernel/goal/index.ts +1 -0
  189. package/packages/kernel/identity/api/index.ts +5 -0
  190. package/packages/kernel/identity/application/identity-service.ts +67 -0
  191. package/packages/kernel/identity/domain/scope.ts +63 -0
  192. package/packages/kernel/identity/domain/semantic-sync.ts +81 -0
  193. package/packages/kernel/identity/domain/types.ts +44 -0
  194. package/packages/kernel/identity/domain/workspace.ts +56 -0
  195. package/packages/kernel/identity/index.ts +1 -0
  196. package/packages/kernel/identity/infrastructure/identity-store.ts +75 -0
  197. package/packages/kernel/memory/api/index.ts +5 -0
  198. package/packages/kernel/memory/application/experience-service.ts +118 -0
  199. package/packages/kernel/memory/application/outcome-service.ts +77 -0
  200. package/packages/kernel/memory/domain/experience.ts +103 -0
  201. package/packages/kernel/memory/domain/operational-prior.ts +92 -0
  202. package/packages/kernel/memory/index.ts +1 -0
  203. package/packages/kernel/progression/api/index.ts +2 -0
  204. package/packages/kernel/progression/application/projector.ts +211 -0
  205. package/packages/kernel/progression/domain/types.ts +116 -0
  206. package/packages/kernel/progression/index.ts +1 -0
  207. package/packages/kernel/scheduler/api/index.ts +6 -0
  208. package/packages/kernel/scheduler/application/continuation-service.ts +212 -0
  209. package/packages/kernel/scheduler/application/eligibility.ts +252 -0
  210. package/packages/kernel/scheduler/application/schedule-service.ts +24 -0
  211. package/packages/kernel/scheduler/application/settlement.ts +197 -0
  212. package/packages/kernel/scheduler/domain/continuation.ts +38 -0
  213. package/packages/kernel/scheduler/domain/schedule.ts +149 -0
  214. package/packages/kernel/scheduler/index.ts +1 -0
  215. package/packages/kernel/scheduler/infrastructure/continuation-dispatch-store.ts +38 -0
  216. package/packages/kernel/scheduler/infrastructure/schedule-store.ts +785 -0
  217. package/packages/kernel/work/api/index.ts +15 -0
  218. package/packages/kernel/work/application/work-service.ts +148 -0
  219. package/packages/kernel/work/domain/admission-policy.ts +34 -0
  220. package/packages/kernel/work/domain/check-receipt.ts +43 -0
  221. package/packages/kernel/work/domain/context-closure-receipt.ts +32 -0
  222. package/packages/kernel/work/domain/engineering-contracts.ts +157 -0
  223. package/packages/kernel/work/domain/engineering-design.ts +281 -0
  224. package/packages/kernel/work/domain/engineering-profile.ts +242 -0
  225. package/packages/kernel/work/domain/execution-concurrency.ts +254 -0
  226. package/packages/kernel/work/domain/execution-snapshot.ts +33 -0
  227. package/packages/kernel/work/domain/implementation-review.ts +510 -0
  228. package/packages/kernel/work/domain/project-engineering-contract.ts +202 -0
  229. package/packages/kernel/work/domain/repository-completion-receipt.ts +73 -0
  230. package/packages/kernel/work/domain/state-machine.ts +259 -0
  231. package/packages/kernel/work/domain/types.ts +528 -0
  232. package/packages/kernel/work/index.ts +1 -0
  233. package/packages/kernel/work/infrastructure/work-contract-store.ts +1876 -0
  234. package/packages/kernel/work/ports/work-contract-store.ts +18 -0
  235. package/packages/plugin-runtime/browser/index.ts +3 -0
  236. package/packages/plugin-runtime/browser/provider-registry.ts +110 -0
  237. package/packages/plugin-runtime/browser/runtime-contract.ts +150 -0
  238. package/packages/plugin-runtime/browser/session-authority.ts +61 -0
  239. package/packages/plugin-runtime/computer/index.ts +6 -0
  240. package/packages/plugin-runtime/computer/provider-error.ts +26 -0
  241. package/packages/plugin-runtime/computer/provider-registration.ts +52 -0
  242. package/packages/plugin-runtime/computer/provider-registry.ts +63 -0
  243. package/packages/plugin-runtime/computer/provider.ts +19 -0
  244. package/packages/plugin-runtime/computer/target-authority.ts +190 -0
  245. package/packages/plugin-runtime/computer/target-persistence.ts +54 -0
  246. package/packages/plugin-runtime/external/index.ts +1 -0
  247. package/packages/plugin-runtime/external/unix-jsonl-transport.ts +457 -0
  248. package/packages/plugin-runtime/index.ts +3 -0
  249. package/packages/protocols/browser/index.ts +1 -0
  250. package/packages/protocols/browser/session.ts +98 -0
  251. package/packages/protocols/computer/contract.ts +199 -0
  252. package/packages/protocols/computer/index.ts +1 -0
  253. package/packages/protocols/failure/contract.ts +158 -0
  254. package/packages/protocols/failure/index.ts +1 -0
  255. package/packages/protocols/handoff/index.ts +1 -0
  256. package/packages/protocols/handoff/status.ts +22 -0
  257. package/packages/protocols/mcp/execution-context.ts +11 -0
  258. package/packages/protocols/mcp/index.ts +2 -0
  259. package/packages/protocols/mcp/tool-contract.ts +42 -0
  260. package/packages/workflow-runtime/api/index.ts +2 -0
  261. package/packages/workflow-runtime/application/interpreter.ts +342 -0
  262. package/packages/workflow-runtime/domain/workflow-asset.ts +223 -0
  263. package/packages/workflow-runtime/index.ts +1 -0
  264. package/scripts/assemble-template.ts +1 -1
  265. package/scripts/benchmark-computer-hotpath.ts +255 -0
  266. package/scripts/benchmark-controller-round2.ts +54 -2
  267. package/scripts/benchmark-ios-agent-device.ts +3 -6
  268. package/scripts/benchmark-mcp-transport.ts +3 -4
  269. package/scripts/benchmark-operational-memory-activation.ts +235 -0
  270. package/scripts/benchmark-operational-shadow.ts +28 -0
  271. package/scripts/bootstrap-runtime-maintenance-recovery.sh +4 -1
  272. package/scripts/canary-chatgpt-provider-delivery.ts +97 -0
  273. package/scripts/canary-controller-semantic-wait.ts +195 -0
  274. package/scripts/canary-global-hook.sh +2 -2
  275. package/scripts/check-mcp-compatibility.ts +173 -7
  276. package/scripts/check-platform-support.mjs +28 -2
  277. package/scripts/check-public-docs.sh +1 -1
  278. package/scripts/check-release-readiness.sh +1 -1
  279. package/scripts/check-repository-hygiene.mjs +92 -0
  280. package/scripts/check-runtime-architecture.mjs +1206 -95
  281. package/scripts/check-source-duplication.mjs +9 -1
  282. package/scripts/check-tarball-install-smoke.sh +98 -15
  283. package/scripts/controller-ngrok-rotation.sh +5 -4
  284. package/scripts/create-project-dirs.sh +10 -74
  285. package/scripts/forge-local-recovery-helper.mjs +204 -0
  286. package/scripts/forge-uu-remote-rescue-helper.d.mts +31 -0
  287. package/scripts/forge-uu-remote-rescue-helper.mjs +409 -0
  288. package/scripts/forge-windows-host-recovery-helper.mjs +136 -0
  289. package/scripts/hook-shim.sh +2 -2
  290. package/scripts/init-project.sh +12 -70
  291. package/scripts/install-desktop-operator-registration.ts +4 -2
  292. package/scripts/install-independent-windows-wsl-recovery.ts +125 -0
  293. package/scripts/install-standalone-recovery.ts +122 -10
  294. package/scripts/install-uu-remote-rescue-registration.ts +74 -0
  295. package/scripts/install-windows-host-recovery-registration.ts +22 -0
  296. package/scripts/lib/controller-home-env.sh +6 -3
  297. package/scripts/lib/project-init-lib.sh +39 -582
  298. package/scripts/migrate-chatgpt-automation-schedules.ts +2 -2
  299. package/scripts/migrate-windows-wsl-controller-home.ts +306 -0
  300. package/scripts/open-source-audit-allowlist.txt +12 -1
  301. package/scripts/portability-bindings.mjs +70 -0
  302. package/scripts/run-bounded-command.mjs +55 -0
  303. package/scripts/run-bun-test-file.ts +22 -6
  304. package/scripts/run-governed-gate.ts +4 -1
  305. package/scripts/smoke-mcp-http-runtime.ts +1 -1
  306. package/scripts/smoke-runtime-recovery.ts +34 -1
  307. package/scripts/smoke-schedule-engine.ts +1 -1
  308. package/scripts/stage-runtime-release.ts +6 -1
  309. package/scripts/test-governance.ts +51 -2
  310. package/src/cli/agent-jobs/job-manager.ts +10 -1
  311. package/src/cli/chatgpt-browser/bind-server.ts +2 -1
  312. package/src/cli/chatgpt-browser/binding.ts +20 -10
  313. package/src/cli/chatgpt-browser/bridge-extension.ts +75 -0
  314. package/src/cli/chatgpt-browser/bridge-provider.ts +376 -11
  315. package/src/cli/chatgpt-browser/engine.ts +10 -11
  316. package/src/cli/chatgpt-browser/native-provider.ts +24 -83
  317. package/src/cli/chatgpt-browser/oracle-provider.ts +5 -3
  318. package/src/cli/chatgpt-browser/types.ts +1 -0
  319. package/src/cli/commands/bootstrap-control.ts +334 -0
  320. package/src/cli/commands/brain-assistant.ts +38 -0
  321. package/src/cli/commands/brain.ts +193 -40
  322. package/src/cli/commands/chatgpt.ts +127 -0
  323. package/src/cli/commands/computer.ts +437 -0
  324. package/src/cli/commands/doctor.ts +18 -1
  325. package/src/cli/commands/init-hook.ts +71 -61
  326. package/src/cli/commands/init.ts +3 -1
  327. package/src/cli/commands/mcp.ts +16 -10
  328. package/src/cli/commands/plugin.ts +38 -12
  329. package/src/cli/commands/recovery.ts +493 -80
  330. package/src/cli/commands/runtime.ts +9 -4
  331. package/src/cli/commands/setup-profile.ts +89 -39
  332. package/src/cli/commands/status.ts +2 -1
  333. package/src/cli/controller/check-runner.ts +487 -98
  334. package/src/cli/controller/context/types.ts +7 -1
  335. package/src/cli/controller/context-pack.ts +23 -3
  336. package/src/cli/controller/issue-store.ts +1 -1
  337. package/src/cli/controller/systemd-user.ts +110 -0
  338. package/src/cli/controller/types.ts +10 -70
  339. package/src/cli/controller/worklog.ts +67 -13
  340. package/src/cli/editing/edit-operation-contract.ts +92 -0
  341. package/src/cli/editing/edit-session.ts +289 -13
  342. package/src/cli/github/plugin.ts +17 -12
  343. package/src/cli/hook/route-registry.ts +3 -5
  344. package/src/cli/hook/runtime.ts +49 -3
  345. package/src/cli/index.ts +3 -0
  346. package/src/cli/local-bridge/connector-freshness.ts +2 -2
  347. package/src/cli/local-bridge/console-automations.ts +2 -2
  348. package/src/cli/local-bridge/facade-api.ts +41 -14
  349. package/src/cli/local-bridge/job-store.ts +1 -1
  350. package/src/cli/local-bridge/server.ts +24 -27
  351. package/src/cli/mcp/access-mode.ts +2 -132
  352. package/src/cli/mcp/access-tools.ts +2 -387
  353. package/src/cli/mcp/audit.ts +2 -32
  354. package/src/cli/mcp/auth.ts +2 -404
  355. package/src/cli/mcp/instructions.ts +2 -34
  356. package/src/cli/mcp/legacy-context.ts +2 -16
  357. package/src/cli/mcp/legacy-tool-service.ts +2 -5308
  358. package/src/cli/mcp/multi-repository.ts +2 -436
  359. package/src/cli/mcp/oauth.ts +2 -375
  360. package/src/cli/mcp/openai-secure-tunnel.ts +2 -0
  361. package/src/cli/mcp/paths.ts +2 -140
  362. package/src/cli/mcp/policy.ts +2 -232
  363. package/src/cli/mcp/post-finalize-work-attribution.ts +2 -150
  364. package/src/cli/mcp/proxy-env.ts +2 -62
  365. package/src/cli/mcp/readiness-projection.ts +2 -24
  366. package/src/cli/mcp/redaction.ts +2 -21
  367. package/src/cli/mcp/repo.ts +2 -24
  368. package/src/cli/mcp/repository-tools.ts +2 -1613
  369. package/src/cli/mcp/server.ts +2 -951
  370. package/src/cli/mcp/setup.ts +2 -737
  371. package/src/cli/mcp/tool-capability-cache.ts +2 -87
  372. package/src/cli/mcp/tool-contract.ts +2 -14
  373. package/src/cli/mcp/tools.ts +2 -9
  374. package/src/cli/mcp/toolset-names.ts +2 -70
  375. package/src/cli/mcp/toolset-selection.ts +2 -41
  376. package/src/cli/mcp/toolset.ts +2 -336
  377. package/src/cli/mcp/transports/AGENTS.md +1 -10
  378. package/src/cli/mcp/transports/CLAUDE.md +1 -10
  379. package/src/cli/mcp/transports/http.ts +2 -1414
  380. package/src/cli/mcp/transports/session-registry.ts +2 -490
  381. package/src/cli/mcp/transports/stdio.ts +2 -8
  382. package/src/cli/mcp/types.ts +2 -41
  383. package/src/cli/mcp/umbrella-tools.ts +2 -117
  384. package/src/cli/repositories/command-executor.ts +64 -18
  385. package/src/cli/repositories/command-scope.ts +117 -1
  386. package/src/cli/repositories/controller-home.ts +119 -1
  387. package/src/cli/repositories/identity.ts +13 -0
  388. package/src/cli/repositories/registry.ts +68 -49
  389. package/src/cli/repositories/repository-snapshot.ts +53 -7
  390. package/src/cli/repositories/runtime-storage.ts +27 -2
  391. package/src/cli/repositories/safe-patch.ts +34 -38
  392. package/src/cli/repositories/selected-path-actions.ts +22 -2
  393. package/src/cli/repositories/structured-git.ts +105 -25
  394. package/src/cli/runtime/helper-runner.ts +7 -0
  395. package/src/cli/runtime-invocation.ts +8 -1
  396. package/src/cli/tools/codegraph.ts +44 -25
  397. package/src/core/adoption/manifest-templates.ts +1 -1
  398. package/src/core/adoption/plan.ts +3 -26
  399. package/src/core/adoption/workflow-contract-plan.ts +17 -9
  400. package/src/effects/process-runner.ts +8 -14
  401. package/src/runtime/context/assistant-context.ts +154 -0
  402. package/src/runtime/context/assistant-work-context.ts +147 -0
  403. package/src/runtime/context/codegraph-cache-boundary.ts +255 -0
  404. package/src/runtime/context/codegraph-read-provider.ts +55 -22
  405. package/src/runtime/context/codegraph-sidecar.cjs +8 -1
  406. package/src/runtime/context/context-closure.ts +268 -0
  407. package/src/runtime/context/context-plane.ts +211 -0
  408. package/src/runtime/context/project-engineering-contract.ts +60 -0
  409. package/src/runtime/control-plane/bootstrap/capability-provider.ts +74 -0
  410. package/src/runtime/control-plane/bootstrap/control-api.ts +57 -0
  411. package/src/runtime/control-plane/bootstrap/index.ts +5 -0
  412. package/src/runtime/control-plane/bootstrap/state-machine.ts +141 -0
  413. package/src/runtime/control-plane/bootstrap/store.ts +21 -0
  414. package/src/runtime/control-plane/bootstrap/types.ts +87 -0
  415. package/src/runtime/control-plane/cleanup-artifact-retention.ts +328 -0
  416. package/src/runtime/control-plane/codegraph-cache-retention.ts +164 -0
  417. package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +320 -0
  418. package/src/runtime/control-plane/execution/content-equivalent-commit-authority.ts +169 -0
  419. package/src/runtime/control-plane/execution/controller-authority-recovery.ts +350 -0
  420. package/src/runtime/control-plane/execution/direct-canonical-work-reconciliation.ts +85 -0
  421. package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +369 -99
  422. package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +103 -15
  423. package/src/runtime/control-plane/execution/implementation-review-content.ts +95 -0
  424. package/src/runtime/control-plane/execution/repository-work-attribution.ts +2 -2
  425. package/src/runtime/control-plane/execution/retained-work-resume.ts +336 -6
  426. package/src/runtime/control-plane/execution/validation.ts +28 -3
  427. package/src/runtime/control-plane/execution/work-authority-reconciler.ts +116 -0
  428. package/src/runtime/control-plane/execution/work-completion-authority.ts +44 -2
  429. package/src/runtime/control-plane/execution/work-evidence-policy.ts +34 -3
  430. package/src/runtime/control-plane/execution/work-execution-support.ts +42 -22
  431. package/src/runtime/control-plane/execution/work-finalization-service.ts +1103 -166
  432. package/src/runtime/control-plane/execution/work-handle-authority.ts +219 -22
  433. package/src/runtime/control-plane/execution/work-handle-store.ts +77 -0
  434. package/src/runtime/control-plane/execution/work-head-settlement.ts +75 -0
  435. package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +145 -23
  436. package/src/runtime/control-plane/execution/work-operation-service.ts +49 -13
  437. package/src/runtime/control-plane/execution/work-preparation-service.ts +31 -15
  438. package/src/runtime/control-plane/execution/work-remote-delivery.ts +1 -1
  439. package/src/runtime/control-plane/execution/work-task-receipt.ts +20 -1
  440. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +407 -76
  441. package/src/runtime/control-plane/execution/work-validation-reconciler.ts +88 -18
  442. package/src/runtime/control-plane/execution/work-verification-context.ts +1 -1
  443. package/src/runtime/control-plane/execution/work-verification-service.ts +258 -4
  444. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +200 -15
  445. package/src/runtime/control-plane/facade/capability-registry.ts +21 -10
  446. package/src/runtime/control-plane/facade/controller-round-relay.ts +3 -1118
  447. package/src/runtime/control-plane/facade/controller-session-store.ts +2 -488
  448. package/src/runtime/control-plane/facade/goal-workloop-access.ts +6 -3
  449. package/src/runtime/control-plane/facade/goal-workloop.ts +972 -137
  450. package/src/runtime/control-plane/facade/handoff-inbox-application.ts +158 -0
  451. package/src/runtime/control-plane/facade/handoff-inbox-store.ts +10 -0
  452. package/src/runtime/control-plane/facade/index.ts +4 -2
  453. package/src/runtime/control-plane/facade/operation-digest.ts +22 -58
  454. package/src/runtime/control-plane/facade/plan-contract-store.ts +1004 -38
  455. package/src/runtime/control-plane/facade/repository-work-admission.ts +19 -1
  456. package/src/runtime/control-plane/facade/requirement-authority.ts +218 -0
  457. package/src/runtime/control-plane/facade/requirement-board.ts +6 -1
  458. package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +48 -0
  459. package/src/runtime/control-plane/facade/semantic-admission.ts +8 -16
  460. package/src/runtime/control-plane/facade/suggested-actions.ts +4 -1
  461. package/src/runtime/control-plane/facade/types.ts +189 -532
  462. package/src/runtime/control-plane/facade/work-admission-policy.ts +84 -35
  463. package/src/runtime/control-plane/facade/work-contract-store.ts +2 -1043
  464. package/src/runtime/control-plane/facade/work-implementation-review.ts +2 -0
  465. package/src/runtime/control-plane/facade/work-state-machine.ts +2 -250
  466. package/src/runtime/control-plane/generated-cache-retention.ts +239 -18
  467. package/src/runtime/control-plane/global-scheduler/durable-admission.ts +12 -1
  468. package/src/runtime/control-plane/global-scheduler/maintenance.ts +76 -13
  469. package/src/runtime/control-plane/global-scheduler/periodic-cleanup-entry.ts +55 -0
  470. package/src/runtime/control-plane/global-scheduler/periodic-cleanup-process.ts +98 -0
  471. package/src/runtime/control-plane/global-scheduler/reconciliation.ts +1 -1
  472. package/src/runtime/control-plane/global-scheduler/scheduler-worker-entry.ts +10 -0
  473. package/src/runtime/control-plane/global-scheduler/scheduler.ts +173 -81
  474. package/src/runtime/control-plane/global-scheduler/worker-launch.ts +18 -6
  475. package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +397 -0
  476. package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +2 -177
  477. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +301 -560
  478. package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +20 -4
  479. package/src/runtime/control-plane/launcher/thin-launcher.ts +50 -4
  480. package/src/runtime/control-plane/lifecycle-retention-metrics.ts +60 -0
  481. package/src/runtime/control-plane/persistence/experience-store.ts +169 -0
  482. package/src/runtime/control-plane/persistence/operational-prior-store.ts +348 -0
  483. package/src/runtime/control-plane/persistence/requirement-store.ts +30 -22
  484. package/src/runtime/control-plane/persistence/sqlite-store.ts +545 -76
  485. package/src/runtime/control-plane/persistence/workflow-content-store.ts +98 -0
  486. package/src/runtime/control-plane/persistence/workflow-registry-store.ts +186 -0
  487. package/src/runtime/control-plane/persistence/workflow-run-store.ts +123 -0
  488. package/src/runtime/control-plane/release-retention.ts +56 -16
  489. package/src/runtime/control-plane/repository-namespace-retention.ts +208 -0
  490. package/src/runtime/control-plane/routing/route-policy.ts +19 -0
  491. package/src/runtime/control-plane/runtime-cleanup.ts +574 -37
  492. package/src/runtime/control-plane/runtime-generation.ts +6 -0
  493. package/src/runtime/control-plane/workspace/semantic-sync-service.ts +465 -0
  494. package/src/runtime/control-plane/workspace/workspace-store.ts +80 -0
  495. package/src/runtime/diagnostics/incident-repair.ts +406 -0
  496. package/src/runtime/diagnostics/mcp-timing.ts +125 -6
  497. package/src/runtime/diagnostics/performance.ts +6 -14
  498. package/src/runtime/diagnostics/read-only-tool.ts +1 -1
  499. package/src/runtime/evidence/artifact-store.ts +65 -2
  500. package/src/runtime/evidence/operational-shadow.ts +38 -0
  501. package/src/runtime/evidence/process-check-receipt.ts +5 -43
  502. package/src/runtime/evidence/sensitive-output.ts +4 -4
  503. package/src/runtime/execution/jobs/receipt-recovery.ts +1 -1
  504. package/src/runtime/execution/jobs/store.ts +121 -2
  505. package/src/runtime/execution/managed-workspace.ts +55 -5
  506. package/src/runtime/execution/process-runtime/canary.ts +19 -5
  507. package/src/runtime/execution/process-runtime/check-classification.ts +48 -0
  508. package/src/runtime/execution/process-runtime/check-facade.ts +23 -9
  509. package/src/runtime/execution/process-runtime/check-receipt.ts +1 -1
  510. package/src/runtime/execution/process-runtime/check-result-retention.ts +132 -0
  511. package/src/runtime/execution/process-runtime/check-result.ts +73 -2
  512. package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +42 -3
  513. package/src/runtime/execution/process-runtime/check-storage.ts +187 -0
  514. package/src/runtime/execution/process-runtime/command-facade.ts +38 -87
  515. package/src/runtime/execution/process-runtime/index.ts +1 -0
  516. package/src/runtime/execution/process-runtime/interactive-admission.ts +2 -1
  517. package/src/runtime/execution/process-runtime/lightweight-managed.ts +32 -1
  518. package/src/runtime/execution/process-runtime/persisted-check.ts +128 -21
  519. package/src/runtime/execution/process-runtime/resource-claims.ts +60 -3
  520. package/src/runtime/execution/process-runtime/runtime.ts +132 -15
  521. package/src/runtime/execution/process-runtime/types.ts +22 -0
  522. package/src/runtime/execution/workers/executor.ts +16 -13
  523. package/src/runtime/execution/workers/worker-entry.ts +1 -1
  524. package/src/runtime/gateway/mcp/execution-tools.ts +2 -207
  525. package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +2 -61
  526. package/src/runtime/gateway/mcp/persisted-check-process.ts +2 -3
  527. package/src/runtime/gateway/mcp/process-tools.ts +2 -289
  528. package/src/runtime/gateway/mcp/router.ts +2 -1125
  529. package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +2 -565
  530. package/src/runtime/gateway/mcp/runtime-tools.ts +2 -6655
  531. package/src/runtime/gateway/mcp/work-validation-reconciler.ts +2 -1
  532. package/src/runtime/maintenance/cleanup.ts +38 -24
  533. package/src/runtime/platform/browser-product-discovery.ts +174 -0
  534. package/src/runtime/platform/computer-platform.ts +14 -0
  535. package/src/runtime/platform/executable-discovery.ts +54 -0
  536. package/src/runtime/platform/fetch-http-server.ts +90 -0
  537. package/src/runtime/platform/service-manager.ts +138 -0
  538. package/src/runtime/platform/windows-host-discovery.ts +118 -0
  539. package/src/runtime/platform/windows-recovery-deployment.ts +67 -0
  540. package/src/runtime/plugins/action-application.ts +135 -0
  541. package/src/runtime/plugins/app-store-connect-adapter.ts +9 -21
  542. package/src/runtime/plugins/browser-adapter.ts +140 -100
  543. package/src/runtime/plugins/browser-automation-service.ts +15 -36
  544. package/src/runtime/plugins/browser-macos-bridge.ts +69 -21
  545. package/src/runtime/plugins/browser-manifest-surface.ts +30 -6
  546. package/src/runtime/plugins/browser-native-session-service.ts +1 -1
  547. package/src/runtime/plugins/browser-provider-registry.ts +2 -109
  548. package/src/runtime/plugins/browser-registration.ts +16 -0
  549. package/src/runtime/plugins/browser-runtime-contract.ts +2 -154
  550. package/src/runtime/plugins/browser-runtime.ts +41 -9
  551. package/src/runtime/plugins/browser-session-authority.ts +101 -291
  552. package/src/runtime/plugins/browser-session-legacy-migration.ts +203 -0
  553. package/src/runtime/plugins/browser-session-store.ts +229 -36
  554. package/src/runtime/plugins/browser-session-types.ts +2 -98
  555. package/src/runtime/plugins/capability-authorization-grants.ts +17 -0
  556. package/src/runtime/plugins/catalog-trust.ts +82 -0
  557. package/src/runtime/plugins/computer-registration.ts +839 -0
  558. package/src/runtime/plugins/config-store.ts +119 -0
  559. package/src/runtime/plugins/desktop-operator-external-policy.ts +932 -0
  560. package/src/runtime/plugins/desktop-operator-registration.ts +111 -8
  561. package/src/runtime/plugins/errors.ts +8 -1
  562. package/src/runtime/plugins/external-adapter.ts +45 -322
  563. package/src/runtime/plugins/external-provider-policy.ts +48 -0
  564. package/src/runtime/plugins/external-registration.ts +9 -1
  565. package/src/runtime/plugins/external-unix-socket-probe.cjs +9 -3
  566. package/src/runtime/plugins/external-unix-socket.ts +64 -193
  567. package/src/runtime/plugins/first-party-external-registration.ts +163 -0
  568. package/src/runtime/plugins/first-party-registry.ts +3 -1
  569. package/src/runtime/plugins/github-adapter.ts +1 -2
  570. package/src/runtime/plugins/gmail-adapter.ts +6 -6
  571. package/src/runtime/plugins/google-calendar-adapter.ts +6 -6
  572. package/src/runtime/plugins/google-shared.ts +31 -46
  573. package/src/runtime/plugins/google-tasks-adapter.ts +6 -6
  574. package/src/runtime/plugins/ios-adapter.ts +1 -2
  575. package/src/runtime/plugins/local-system-adapter.ts +180 -0
  576. package/src/runtime/plugins/macos-capability-broker.ts +15 -105
  577. package/src/runtime/plugins/resend-adapter.ts +15 -24
  578. package/src/runtime/plugins/store.ts +493 -51
  579. package/src/runtime/plugins/types.ts +8 -1
  580. package/src/runtime/plugins/uu-remote-rescue-registration.ts +155 -0
  581. package/src/runtime/plugins/windows-host-recovery-install.ts +68 -0
  582. package/src/runtime/plugins/windows-host-recovery-registration.ts +85 -0
  583. package/src/runtime/plugins/xiaohongshu-publish.ts +86 -430
  584. package/src/runtime/projections/controller-context.ts +12 -6
  585. package/src/runtime/projections/git-status-sampler.ts +73 -22
  586. package/src/runtime/projections/materialized-view.ts +14 -8
  587. package/src/runtime/recovery/capability-action-application.ts +228 -0
  588. package/src/runtime/recovery/index.ts +3 -0
  589. package/src/runtime/recovery/lifecycle-inventory.ts +338 -0
  590. package/src/runtime/recovery/local-jobs-repair.ts +14 -14
  591. package/src/runtime/recovery/maintenance-executor.ts +358 -76
  592. package/src/runtime/recovery/quarantine-retention.ts +256 -0
  593. package/src/runtime/release/identity.ts +6 -0
  594. package/src/runtime/resources/leases/store.ts +1 -1
  595. package/src/runtime/root/active-execution-power-assertion.ts +139 -0
  596. package/src/runtime/root/assistant-learning-loop.ts +45 -0
  597. package/src/runtime/root/browser-session-composition.ts +59 -0
  598. package/src/runtime/root/computer-composition.ts +191 -0
  599. package/src/runtime/root/computer-target-composition.ts +16 -0
  600. package/src/runtime/root/computer-target-persistence.ts +39 -0
  601. package/src/runtime/root/controller-round-composition.ts +107 -0
  602. package/src/runtime/root/controller-services.ts +2 -0
  603. package/src/runtime/root/entry.ts +4 -3
  604. package/src/runtime/root/gateway-adapter.ts +3 -3
  605. package/src/runtime/root/local-bridge.ts +5 -2
  606. package/src/runtime/root/mcp-transport.ts +5 -5
  607. package/src/runtime/root/package-connector-service.ts +108 -56
  608. package/src/runtime/root/package-runtime-release.ts +85 -18
  609. package/src/runtime/root/package-runtime-service.ts +60 -97
  610. package/src/runtime/root/release-execution-canary.ts +71 -0
  611. package/src/runtime/root/release-loader.ts +68 -0
  612. package/src/runtime/root/release-manifest.ts +106 -2
  613. package/src/runtime/root/release-materialize.ts +103 -4
  614. package/src/runtime/root/release-store.ts +31 -2
  615. package/src/runtime/root/runtime.ts +240 -25
  616. package/src/runtime/root/scheduled-controller-composition.ts +51 -0
  617. package/src/runtime/root/scheduler.ts +12 -4
  618. package/src/runtime/root/service-runner.ts +1 -1
  619. package/src/runtime/root/service.ts +41 -16
  620. package/src/runtime/root/status.ts +1 -0
  621. package/src/runtime/root/types.ts +24 -1
  622. package/src/runtime/shared/local-bridge-surface.ts +1 -1
  623. package/src/runtime/shared/process-environment.ts +19 -4
  624. package/src/runtime/shared/storage-capacity.ts +68 -0
  625. package/src/runtime/standalone-recovery/controller-home-migration.ts +1116 -0
  626. package/src/runtime/standalone-recovery/core.ts +984 -230
  627. package/src/runtime/standalone-recovery/entry.ts +182 -51
  628. package/src/runtime/standalone-recovery/independent-host-rescue.ts +172 -0
  629. package/src/runtime/standalone-recovery/installer.ts +212 -104
  630. package/src/runtime/standalone-recovery/mcp-server.ts +243 -0
  631. package/src/runtime/standalone-recovery/mutation-identity-contract.ts +21 -0
  632. package/src/runtime/standalone-recovery/operation-lock.ts +160 -0
  633. package/src/runtime/standalone-recovery/performance.ts +135 -0
  634. package/src/runtime/standalone-recovery/release.ts +5 -0
  635. package/src/runtime/watchdog/workflow-watchdog.ts +1 -1
  636. package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +1 -1
  637. package/src/runtime/workflow/schedules/engine.ts +191 -343
  638. package/src/runtime/workflow/schedules/pending-activation.ts +1 -1
  639. package/src/runtime/workflow/schedules/settlement.ts +2 -191
  640. package/src/runtime/workflow/schedules/store.ts +2 -607
  641. package/src/runtime/workflow/schedules/types.ts +2 -127
  642. package/src/runtime/workflow/schedules/work-continuation.ts +180 -15
  643. package/src/runtime/workflows/first-party/xiaohongshu.ts +122 -0
  644. package/src/runtime/workflows/runtime.ts +486 -0
  645. package/src/testing/test-governance.ts +90 -29
  646. package/assets/templates/helpers/archive-architecture-request.sh +0 -244
  647. package/docs/architecture/history/README.md +0 -7
  648. package/docs/architecture/history/chatgpt-handoff-facade.md +0 -397
  649. package/docs/architecture/history/global-hook-runtime.md +0 -166
  650. package/docs/architecture/history/ios-semantic-automation-provider-v2.md +0 -170
  651. package/docs/architecture/requests/archive/2026/20260528-154740-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
  652. package/docs/architecture/requests/archive/2026/20260528-154816-assets-hooks-assets-hooks-hook-input-sh.md +0 -59
  653. package/docs/architecture/requests/archive/2026/20260528-161851-ai-harness-workflow-contract-json-ai-harness-workflow-contract-json.md +0 -59
  654. package/docs/architecture/requests/archive/2026/20260528-161853-scripts-check-task-workflow-sh-scripts-check-task-workflow-sh.md +0 -59
  655. package/docs/architecture/requests/archive/2026/20260528-161911-assets-workflow-contract-v1-json-assets-workflow-contract-v1-json.md +0 -59
  656. package/docs/architecture/requests/archive/2026/20260528-222416-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
  657. package/docs/architecture/requests/archive/2026/20260528-222444-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
  658. package/docs/architecture/requests/archive/2026/20260528-222457-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
  659. package/docs/architecture/requests/archive/2026/20260528-222648-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
  660. package/docs/architecture/requests/archive/2026/20260528-222705-ai-hooks-ai-hooks-worktree-guard-sh.md +0 -59
  661. package/docs/architecture/requests/archive/2026/20260528-222726-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  662. package/docs/architecture/requests/archive/2026/20260528-222727-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  663. package/docs/architecture/requests/archive/2026/20260528-224736-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
  664. package/docs/architecture/requests/archive/2026/20260528-233259-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  665. package/docs/architecture/requests/archive/2026/20260528-233335-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
  666. package/docs/architecture/requests/archive/2026/20260528-233456-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  667. package/docs/architecture/requests/archive/2026/20260528-233457-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
  668. package/docs/architecture/requests/archive/2026/20260528-233637-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  669. package/docs/architecture/requests/archive/2026/20260528-233638-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
  670. package/docs/architecture/requests/archive/2026/20260529-000322-root-package-json.md +0 -59
  671. package/docs/architecture/requests/archive/2026/20260529-004238-ai-hooks-ai-hooks-lib-workflow-state-sh.md +0 -59
  672. package/docs/architecture/requests/archive/2026/20260529-020654-ai-harness-policy-json-ai-harness-policy-json.md +0 -63
  673. package/docs/architecture/requests/archive/2026/20260529-094236-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -60
  674. package/docs/architecture/requests/archive/2026/20260529-094323-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -60
  675. package/docs/architecture/requests/archive/2026/20260529-094331-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -60
  676. package/docs/architecture/requests/archive/2026/20260529-094339-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -60
  677. package/docs/architecture/requests/archive/2026/20260529-094430-assets-hooks-assets-hooks-session-start-context-sh.md +0 -60
  678. package/docs/architecture/requests/archive/2026/20260529-094446-ai-hooks-ai-hooks-session-start-context-sh.md +0 -60
  679. package/docs/architecture/requests/archive/2026/20260613-002040-runtime-harness-hook-adapters.md +0 -68
  680. package/docs/architecture/requests/archive/2026/root.md +0 -68
  681. package/docs/architecture/requests/archive/2026/runtime-harness-hook-adapters.md +0 -76
  682. package/docs/architecture/requests/archive/2026/verification-evals-checks.md +0 -68
  683. package/docs/architecture/requests/archive/2026/workflow-engine-contract-assets.md +0 -69
  684. package/scripts/archive-architecture-request.sh +0 -4
  685. package/scripts/run-skill-evals.ts +0 -1022
@@ -1,6 +1,7 @@
1
1
  import type {
2
2
  AssistantPluginActionDescriptor,
3
3
  AssistantPluginActionExecutionInput,
4
+ AssistantPluginBuildContext,
4
5
  AssistantPluginCapability,
5
6
  AssistantPluginManifest,
6
7
  AssistantPluginPermissionScope,
@@ -9,7 +10,6 @@ import { AssistantPluginError } from './errors';
9
10
  import {
10
11
  type GoogleCalendarPluginConfig,
11
12
  googleApiRequest,
12
- googleCalendarPluginConfigPath,
13
13
  googlePermission,
14
14
  loadGoogleCalendarPluginConfig,
15
15
  pluginStateFromGoogleAuth,
@@ -391,9 +391,9 @@ function calendarProvider(config: GoogleCalendarPluginConfig, repoRoot?: string)
391
391
  return config.provider === 'mock' ? mockCalendarProvider() : liveCalendarProvider(config, repoRoot);
392
392
  }
393
393
 
394
- export function buildGoogleCalendarPluginManifest(previousRevision = 0, previousUpdatedAt?: string, repoRoot?: string): AssistantPluginManifest {
394
+ export function buildGoogleCalendarPluginManifest(previousRevision = 0, previousUpdatedAt?: string, repoRoot?: string, context?: AssistantPluginBuildContext): AssistantPluginManifest {
395
395
  const root = repoRoot ?? process.cwd();
396
- const config = loadGoogleCalendarPluginConfig(root);
396
+ const config = loadGoogleCalendarPluginConfig(root, context);
397
397
  const auth = resolveGoogleAuth('calendar', config, { repoRoot: root });
398
398
  const state = pluginStateFromGoogleAuth(config, auth);
399
399
  return {
@@ -407,7 +407,7 @@ export function buildGoogleCalendarPluginManifest(previousRevision = 0, previous
407
407
  authority: {
408
408
  strategy: 'derived',
409
409
  duplicateStateAllowed: false,
410
- sourceOfTruth: [`repo-local:${googleCalendarPluginConfigPath()}`, 'env:FORGE_*_ACCESS_TOKEN'],
410
+ sourceOfTruth: ['controller-home:repositories/<repoId>/plugins/config/google-calendar.json', 'env:FORGE_*_ACCESS_TOKEN'],
411
411
  },
412
412
  enabled: config.enabled,
413
413
  lifecycle: {
@@ -427,11 +427,11 @@ export function buildGoogleCalendarPluginManifest(previousRevision = 0, previous
427
427
  }
428
428
 
429
429
  export async function executeGoogleCalendarPluginAction(input: AssistantPluginActionExecutionInput): Promise<Record<string, unknown>> {
430
- const current = loadGoogleCalendarPluginConfig(input.repoRoot);
430
+ const current = loadGoogleCalendarPluginConfig(input.repoRoot, input);
431
431
  switch (input.actionId) {
432
432
  case 'configure': {
433
433
  const args = input.args;
434
- const config = saveGoogleCalendarPluginConfig(input.repoRoot, {
434
+ const config = saveGoogleCalendarPluginConfig(input, {
435
435
  enabled: typeof args.enabled === 'boolean' ? args.enabled : current.enabled,
436
436
  provider: args.provider === 'google-workspace' ? 'google-workspace' : args.provider === 'mock' ? 'mock' : current.provider,
437
437
  accountEmail: args.clear_account_email === true ? undefined : stringValue(args.account_email) ?? current.accountEmail,
@@ -1,6 +1,4 @@
1
1
  import { createHash } from 'crypto';
2
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
3
- import { dirname, join } from 'path';
4
2
  import type {
5
3
  AssistantPluginHealth,
6
4
  AssistantPluginLifecycleState,
@@ -9,6 +7,7 @@ import type {
9
7
  import { AssistantPluginError, toAssistantPluginError } from './errors';
10
8
  import { bootstrapManagedRuntimeEnv } from '../shared/managed-env';
11
9
  import { readStoredGoogleRefreshToken } from '../safe-tooling/google-credential-store';
10
+ import { readRepositoryPluginConfig, writeRepositoryPluginConfig, type RepositoryPluginConfigContext } from './config-store';
12
11
 
13
12
  export type GoogleProviderKind = 'mock' | 'google-workspace';
14
13
  export type GoogleService = 'gmail' | 'calendar' | 'tasks';
@@ -59,7 +58,6 @@ export interface GoogleApiRequestOptions {
59
58
  timeoutMs?: number;
60
59
  }
61
60
 
62
- const CONFIG_ROOT = '.forge/plugins';
63
61
  const REFRESH_REQUIRED_ACCESS_TOKEN = '__forge_refresh_required__';
64
62
 
65
63
  interface CachedGoogleCredential {
@@ -144,10 +142,6 @@ export function installGoogleAccessToken(service: GoogleService, accessToken: st
144
142
  });
145
143
  }
146
144
 
147
- function repoPluginConfigPath(repoRoot: string, pluginId: string): string {
148
- return join(repoRoot, CONFIG_ROOT, `${pluginId}.json`);
149
- }
150
-
151
145
  function stringValue(value: unknown): string | undefined {
152
146
  return typeof value === 'string' && value.trim() ? value.trim() : undefined;
153
147
  }
@@ -219,75 +213,66 @@ export function normalizeGoogleTasksPluginConfig(raw: Partial<GoogleTasksPluginC
219
213
 
220
214
  function loadPluginConfig<T extends GooglePluginConfig>(
221
215
  repoRoot: string,
216
+ context: Pick<RepositoryPluginConfigContext, 'controllerHome' | 'repoId'> | undefined,
222
217
  pluginId: string,
223
218
  normalize: (raw: Partial<T>) => T,
224
219
  defaults: () => T,
225
220
  ): T {
226
- const path = repoPluginConfigPath(repoRoot, pluginId);
227
- if (!existsSync(path)) return defaults();
228
- try {
229
- return normalize(JSON.parse(readFileSync(path, 'utf-8')) as Partial<T>);
230
- } catch {
231
- return defaults();
232
- }
221
+ if (!context) return defaults();
222
+ const persisted = readRepositoryPluginConfig<Partial<T>>({ ...context, repoRoot }, pluginId);
223
+ return persisted ? normalize(persisted) : defaults();
233
224
  }
234
225
 
235
226
  function writePluginConfig<T extends GooglePluginConfig>(
236
- repoRoot: string,
227
+ context: RepositoryPluginConfigContext,
237
228
  pluginId: string,
238
229
  config: T,
239
230
  ): T {
240
- const path = repoPluginConfigPath(repoRoot, pluginId);
241
- mkdirSync(dirname(path), { recursive: true });
242
- writeFileSync(path, `${JSON.stringify(config, null, 2)}\n`, 'utf-8');
243
- return config;
244
- }
245
-
246
- export function gmailPluginConfigPath(): string {
247
- return `${CONFIG_ROOT}/gmail.json`;
248
- }
249
-
250
- export function googleCalendarPluginConfigPath(): string {
251
- return `${CONFIG_ROOT}/google-calendar.json`;
231
+ return writeRepositoryPluginConfig(context, pluginId, config);
252
232
  }
253
233
 
254
- export function googleTasksPluginConfigPath(): string {
255
- return `${CONFIG_ROOT}/google-tasks.json`;
256
- }
257
-
258
- export function loadGmailPluginConfig(repoRoot: string): GmailPluginConfig {
259
- return loadPluginConfig(repoRoot, 'gmail', normalizeGmailPluginConfig, defaultGmailPluginConfig);
234
+ export function loadGmailPluginConfig(
235
+ repoRoot: string,
236
+ context?: Pick<RepositoryPluginConfigContext, 'controllerHome' | 'repoId'>,
237
+ ): GmailPluginConfig {
238
+ return loadPluginConfig(repoRoot, context, 'gmail', normalizeGmailPluginConfig, defaultGmailPluginConfig);
260
239
  }
261
240
 
262
- export function loadGoogleCalendarPluginConfig(repoRoot: string): GoogleCalendarPluginConfig {
263
- return loadPluginConfig(repoRoot, 'google-calendar', normalizeGoogleCalendarPluginConfig, defaultGoogleCalendarPluginConfig);
241
+ export function loadGoogleCalendarPluginConfig(
242
+ repoRoot: string,
243
+ context?: Pick<RepositoryPluginConfigContext, 'controllerHome' | 'repoId'>,
244
+ ): GoogleCalendarPluginConfig {
245
+ return loadPluginConfig(repoRoot, context, 'google-calendar', normalizeGoogleCalendarPluginConfig, defaultGoogleCalendarPluginConfig);
264
246
  }
265
247
 
266
- export function loadGoogleTasksPluginConfig(repoRoot: string): GoogleTasksPluginConfig {
267
- return loadPluginConfig(repoRoot, 'google-tasks', normalizeGoogleTasksPluginConfig, defaultGoogleTasksPluginConfig);
248
+ export function loadGoogleTasksPluginConfig(
249
+ repoRoot: string,
250
+ context?: Pick<RepositoryPluginConfigContext, 'controllerHome' | 'repoId'>,
251
+ ): GoogleTasksPluginConfig {
252
+ return loadPluginConfig(repoRoot, context, 'google-tasks', normalizeGoogleTasksPluginConfig, defaultGoogleTasksPluginConfig);
268
253
  }
269
254
 
270
255
  export type GooglePluginConfigPatch<T extends GooglePluginConfig> = Partial<Omit<T, 'schemaVersion'>>;
271
256
 
272
- export function saveGmailPluginConfig(repoRoot: string, patch: GooglePluginConfigPatch<GmailPluginConfig>): GmailPluginConfig {
273
- const current = loadGmailPluginConfig(repoRoot);
274
- return writePluginConfig(repoRoot, 'gmail', normalizeGmailPluginConfig({ ...current, ...patch }));
257
+ export function saveGmailPluginConfig(context: RepositoryPluginConfigContext, patch: GooglePluginConfigPatch<GmailPluginConfig>): GmailPluginConfig {
258
+ const current = loadGmailPluginConfig(context.repoRoot, context);
259
+ return writePluginConfig(context, 'gmail', normalizeGmailPluginConfig({ ...current, ...patch }));
275
260
  }
276
261
 
277
262
  export function saveGoogleCalendarPluginConfig(
278
- repoRoot: string,
263
+ context: RepositoryPluginConfigContext,
279
264
  patch: GooglePluginConfigPatch<GoogleCalendarPluginConfig>,
280
265
  ): GoogleCalendarPluginConfig {
281
- const current = loadGoogleCalendarPluginConfig(repoRoot);
282
- return writePluginConfig(repoRoot, 'google-calendar', normalizeGoogleCalendarPluginConfig({ ...current, ...patch }));
266
+ const current = loadGoogleCalendarPluginConfig(context.repoRoot, context);
267
+ return writePluginConfig(context, 'google-calendar', normalizeGoogleCalendarPluginConfig({ ...current, ...patch }));
283
268
  }
284
269
 
285
270
  export function saveGoogleTasksPluginConfig(
286
- repoRoot: string,
271
+ context: RepositoryPluginConfigContext,
287
272
  patch: GooglePluginConfigPatch<GoogleTasksPluginConfig>,
288
273
  ): GoogleTasksPluginConfig {
289
- const current = loadGoogleTasksPluginConfig(repoRoot);
290
- return writePluginConfig(repoRoot, 'google-tasks', normalizeGoogleTasksPluginConfig({ ...current, ...patch }));
274
+ const current = loadGoogleTasksPluginConfig(context.repoRoot, context);
275
+ return writePluginConfig(context, 'google-tasks', normalizeGoogleTasksPluginConfig({ ...current, ...patch }));
291
276
  }
292
277
 
293
278
  function tokenEnvNames(service: GoogleService): string[] {
@@ -1,6 +1,7 @@
1
1
  import type {
2
2
  AssistantPluginActionDescriptor,
3
3
  AssistantPluginActionExecutionInput,
4
+ AssistantPluginBuildContext,
4
5
  AssistantPluginCapability,
5
6
  AssistantPluginManifest,
6
7
  AssistantPluginPermissionScope,
@@ -10,7 +11,6 @@ import {
10
11
  type GoogleTasksPluginConfig,
11
12
  googleApiRequest,
12
13
  googlePermission,
13
- googleTasksPluginConfigPath,
14
14
  loadGoogleTasksPluginConfig,
15
15
  pluginStateFromGoogleAuth,
16
16
  resolveGoogleAuth,
@@ -454,9 +454,9 @@ function tasksProvider(config: GoogleTasksPluginConfig, repoRoot?: string): Task
454
454
  return config.provider === 'mock' ? mockTasksProvider() : liveTasksProvider(config, repoRoot);
455
455
  }
456
456
 
457
- export function buildGoogleTasksPluginManifest(previousRevision = 0, previousUpdatedAt?: string, repoRoot?: string): AssistantPluginManifest {
457
+ export function buildGoogleTasksPluginManifest(previousRevision = 0, previousUpdatedAt?: string, repoRoot?: string, context?: AssistantPluginBuildContext): AssistantPluginManifest {
458
458
  const root = repoRoot ?? process.cwd();
459
- const config = loadGoogleTasksPluginConfig(root);
459
+ const config = loadGoogleTasksPluginConfig(root, context);
460
460
  const auth = resolveGoogleAuth('tasks', config, { repoRoot: root });
461
461
  const state = pluginStateFromGoogleAuth(config, auth);
462
462
  return {
@@ -470,7 +470,7 @@ export function buildGoogleTasksPluginManifest(previousRevision = 0, previousUpd
470
470
  authority: {
471
471
  strategy: 'derived',
472
472
  duplicateStateAllowed: false,
473
- sourceOfTruth: [`repo-local:${googleTasksPluginConfigPath()}`, 'env:FORGE_*_ACCESS_TOKEN'],
473
+ sourceOfTruth: ['controller-home:repositories/<repoId>/plugins/config/google-tasks.json', 'env:FORGE_*_ACCESS_TOKEN'],
474
474
  },
475
475
  enabled: config.enabled,
476
476
  lifecycle: {
@@ -490,11 +490,11 @@ export function buildGoogleTasksPluginManifest(previousRevision = 0, previousUpd
490
490
  }
491
491
 
492
492
  export async function executeGoogleTasksPluginAction(input: AssistantPluginActionExecutionInput): Promise<Record<string, unknown>> {
493
- const current = loadGoogleTasksPluginConfig(input.repoRoot);
493
+ const current = loadGoogleTasksPluginConfig(input.repoRoot, input);
494
494
  switch (input.actionId) {
495
495
  case 'configure': {
496
496
  const args = input.args;
497
- const config = saveGoogleTasksPluginConfig(input.repoRoot, {
497
+ const config = saveGoogleTasksPluginConfig(input, {
498
498
  enabled: typeof args.enabled === 'boolean' ? args.enabled : current.enabled,
499
499
  provider: args.provider === 'google-workspace' ? 'google-workspace' : args.provider === 'mock' ? 'mock' : current.provider,
500
500
  accountEmail: args.clear_account_email === true ? undefined : stringValue(args.account_email) ?? current.accountEmail,
@@ -43,7 +43,6 @@ import {
43
43
  } from './ios-physical-device';
44
44
 
45
45
  const IOS_PLUGIN_ID = 'ios';
46
- const CONFIG_ROOT = '.forge/plugins';
47
46
 
48
47
  function now(): string {
49
48
  return new Date().toISOString();
@@ -414,7 +413,7 @@ export function buildIosPluginManifest(previousRevision = 0, previousUpdatedAt?:
414
413
  authority: {
415
414
  strategy: 'derived',
416
415
  duplicateStateAllowed: false,
417
- sourceOfTruth: ['local:xcodebuild', 'local:simctl', 'local:devicectl', 'local:agent-device-capability-contract', 'process-env:DEVELOPER_DIR', 'process-env:AGENT_DEVICE_IOS_TEAM_ID', 'process-env:AGENT_DEVICE_IOS_BUNDLE_ID', `repo-local:${CONFIG_ROOT}/ios.json`],
416
+ sourceOfTruth: ['local:xcodebuild', 'local:simctl', 'local:devicectl', 'local:agent-device-capability-contract', 'process-env:DEVELOPER_DIR', 'process-env:AGENT_DEVICE_IOS_TEAM_ID', 'process-env:AGENT_DEVICE_IOS_BUNDLE_ID'],
418
417
  },
419
418
  enabled,
420
419
  lifecycle: {
@@ -16,6 +16,9 @@ import {
16
16
  } from 'fs';
17
17
  import { dirname, extname, join, resolve } from 'path';
18
18
  import { forgeRuntimeServicePaths } from '../root/service';
19
+ import { createRecoveryConfig, loadRecoveryConfig, repairPublicTunnel } from '../standalone-recovery/core';
20
+ import { activateRecoveryRelease, recoverySourceIdentity, stageRecoveryRelease } from '../standalone-recovery/installer';
21
+ import { readCurrentRecoveryRelease, type RecoveryReleaseDescriptor } from '../standalone-recovery/release';
19
22
  import {
20
23
  WorkspaceTargetGrantError,
21
24
  authorizeWorkspaceTargetGrant,
@@ -48,6 +51,7 @@ import {
48
51
  assertRepositoryCommandInputAllowed,
49
52
  } from '../../cli/repositories/command-scope';
50
53
  import { runCanonicalCommand } from '../../cli/repositories/command-executor';
54
+ import { findRegisteredRepositoryByCheckoutRoot, listRepositories, repositoryCheckoutLifecycle } from '../../cli/repositories/registry';
51
55
 
52
56
  const PLUGIN_ID = 'local_system';
53
57
  const MAX_OUTPUT_BYTES = 64 * 1024;
@@ -73,6 +77,11 @@ export interface LocalSystemPluginHooks {
73
77
  runCommand?: (command: string, args: string[], timeoutMs?: number) => CommandResult;
74
78
  signalProcess?: (pid: number, signal: NodeJS.Signals) => void;
75
79
  scheduleLaunchAgentRestart?: (service: string) => { pid: number };
80
+ upgradeStandaloneRecovery?: (controllerHome: string) => Promise<Record<string, unknown>>;
81
+ repairPublicTunnel?: typeof repairPublicTunnel;
82
+ recoverySourceIdentity?: typeof recoverySourceIdentity;
83
+ stageRecoveryRelease?: typeof stageRecoveryRelease;
84
+ activateRecoveryRelease?: typeof activateRecoveryRelease;
76
85
  }
77
86
 
78
87
  let hooks: LocalSystemPluginHooks = {};
@@ -625,6 +634,171 @@ export function startVerifiedUserLaunchAgent(labelValue: unknown, expectedProgra
625
634
  return { started: true, label: identity.label, service: identity.service, plistPath: identity.plistPath, bootstrapCommand, enableCommand: enabled.command, startCommand: started.command };
626
635
  }
627
636
 
637
+ function boundedRecoveryRelease(release: RecoveryReleaseDescriptor | undefined): Record<string, unknown> | undefined {
638
+ if (!release) return undefined;
639
+ return {
640
+ releaseRevision: release.releaseRevision,
641
+ sourceCommit: release.sourceCommit,
642
+ manifestSha256: release.manifestSha256,
643
+ legacy: release.legacy,
644
+ };
645
+ }
646
+
647
+ interface RecoveryUpgradeSourceRepair {
648
+ performed: true;
649
+ repositoryId: string;
650
+ previousSourceRoot: string;
651
+ currentSourceRoot: string;
652
+ }
653
+
654
+ function resolveRecoveryUpgradeSource(controllerHome: string, configuredSourceRoot: string): {
655
+ sourceRoot: string;
656
+ repositoryId: string;
657
+ repair?: RecoveryUpgradeSourceRepair;
658
+ } {
659
+ const configured = resolve(configuredSourceRoot);
660
+ if (existsSync(configured)) {
661
+ const owner = findRegisteredRepositoryByCheckoutRoot(configured, controllerHome);
662
+ if (!owner) throw new Error(`RECOVERY_SOURCE_REPOSITORY_NOT_REGISTERED: ${configured}`);
663
+ return { sourceRoot: configured, repositoryId: owner.repoId };
664
+ }
665
+
666
+ const owners = listRepositories(controllerHome)
667
+ .filter((repository) => repository.enabled !== false)
668
+ .filter((repository) => repository.checkouts.some((checkout) => (
669
+ checkout.worktree === true
670
+ && repositoryCheckoutLifecycle(checkout) !== 'active'
671
+ && [checkout.localRoot, checkout.canonicalRoot]
672
+ .filter((candidate): candidate is string => Boolean(candidate?.trim()))
673
+ .some((candidate) => resolve(candidate) === configured)
674
+ )));
675
+ if (owners.length !== 1) {
676
+ throw new Error(owners.length === 0
677
+ ? `RECOVERY_SOURCE_REPAIR_LINEAGE_NOT_FOUND: ${configured}`
678
+ : `RECOVERY_SOURCE_REPAIR_LINEAGE_AMBIGUOUS: ${configured}`);
679
+ }
680
+ const owner = owners[0]!;
681
+ const canonical = resolve(owner.canonicalRoot);
682
+ if (!existsSync(canonical)) {
683
+ throw new Error(`RECOVERY_SOURCE_REPAIR_CANONICAL_MISSING: ${canonical}`);
684
+ }
685
+ return {
686
+ sourceRoot: canonical,
687
+ repositoryId: owner.repoId,
688
+ repair: {
689
+ performed: true,
690
+ repositoryId: owner.repoId,
691
+ previousSourceRoot: configured,
692
+ currentSourceRoot: canonical,
693
+ },
694
+ };
695
+ }
696
+
697
+ async function upgradeStandaloneRecovery(controllerHome: string): Promise<Record<string, unknown>> {
698
+ if (hooks.upgradeStandaloneRecovery) return hooks.upgradeStandaloneRecovery(controllerHome);
699
+ const config = loadRecoveryConfig(controllerHome);
700
+ const configuredSourceRoot = config.primaryRuntimeSourceRoot?.trim();
701
+ if (!configuredSourceRoot) {
702
+ throw new AssistantPluginError(
703
+ 'LOCAL_SYSTEM_RECOVERY_SOURCE_UNCONFIGURED',
704
+ 'Standalone Recovery upgrade requires primaryRuntimeSourceRoot in the installed Recovery configuration.',
705
+ { retryable: false },
706
+ );
707
+ }
708
+ let sourceCommit = '';
709
+ let candidate: RecoveryReleaseDescriptor | undefined;
710
+ let sourceRepair: RecoveryUpgradeSourceRepair | undefined;
711
+ try {
712
+ const resolvedSource = resolveRecoveryUpgradeSource(controllerHome, configuredSourceRoot);
713
+ sourceRepair = resolvedSource.repair;
714
+ const source = (hooks.recoverySourceIdentity ?? recoverySourceIdentity)(resolvedSource.sourceRoot);
715
+ sourceCommit = source.sourceCommit;
716
+ const current = readCurrentRecoveryRelease(controllerHome);
717
+ if (current && !current.legacy && current.cleanWorkspace && current.sourceCommit === source.sourceCommit) {
718
+ candidate = current;
719
+ } else {
720
+ const staged = (hooks.stageRecoveryRelease ?? stageRecoveryRelease)({ controllerHome, sourceRoot: source.sourceRoot });
721
+ candidate = staged.release;
722
+ if (candidate.sourceCommit !== source.sourceCommit || !candidate.cleanWorkspace) {
723
+ throw new Error('RECOVERY_RELEASE_SOURCE_IDENTITY_DRIFT');
724
+ }
725
+ }
726
+ const sourceAuthorityChanged = sourceRepair || config.primaryRuntimeSourceRepositoryId !== resolvedSource.repositoryId;
727
+ const activationConfig = sourceAuthorityChanged
728
+ ? { ...config, primaryRuntimeSourceRoot: source.sourceRoot, primaryRuntimeSourceRepositoryId: resolvedSource.repositoryId }
729
+ : config;
730
+ const activated = await (hooks.activateRecoveryRelease ?? activateRecoveryRelease)({ controllerHome, config: activationConfig, candidate });
731
+ if (sourceAuthorityChanged) {
732
+ createRecoveryConfig(controllerHome, {
733
+ primaryRuntimeSourceRoot: source.sourceRoot,
734
+ primaryRuntimeSourceRepositoryId: resolvedSource.repositoryId,
735
+ });
736
+ }
737
+ return {
738
+ upgraded: activated.noOp !== true,
739
+ noOp: activated.noOp === true,
740
+ sourceCommit,
741
+ sourceRepair: sourceRepair ?? { performed: false },
742
+ candidateRelease: boundedRecoveryRelease(candidate),
743
+ currentRelease: boundedRecoveryRelease(activated.release),
744
+ previousRelease: boundedRecoveryRelease(activated.previous),
745
+ migratedLegacyRelease: boundedRecoveryRelease(activated.migratedLegacy),
746
+ verification: {
747
+ ok: activated.verification.ok,
748
+ gatewayPid: activated.verification.gatewayPid,
749
+ watchdogPid: activated.verification.watchdogPid,
750
+ },
751
+ rollback: { performed: false },
752
+ };
753
+ } catch (error) {
754
+ const message = error instanceof Error ? error.message : String(error);
755
+ const rolledBack = message.includes('RECOVERY_RELEASE_ACTIVATION_FAILED_ROLLED_BACK');
756
+ throw new AssistantPluginError(
757
+ 'LOCAL_SYSTEM_RECOVERY_UPGRADE_FAILED',
758
+ bounded(message, 2_000).content,
759
+ {
760
+ retryable: message.includes('RECOVERY_RELEASE_BUSY'),
761
+ details: {
762
+ sourceCommit: sourceCommit || undefined,
763
+ sourceRepair,
764
+ candidateRelease: boundedRecoveryRelease(candidate),
765
+ rollback: { performed: rolledBack },
766
+ },
767
+ },
768
+ );
769
+ }
770
+ }
771
+
772
+ async function repairStandaloneRecoveryTunnel(controllerHome: string): Promise<Record<string, unknown>> {
773
+ const config = loadRecoveryConfig(controllerHome);
774
+ try {
775
+ const result = await (hooks.repairPublicTunnel ?? repairPublicTunnel)(config);
776
+ if (!result.ok) {
777
+ throw new AssistantPluginError(
778
+ 'LOCAL_SYSTEM_RECOVERY_TUNNEL_REPAIR_FAILED',
779
+ bounded(result.detail, 2_000).content,
780
+ { retryable: result.attempted === true || result.detail.includes('cooldown') },
781
+ );
782
+ }
783
+ return {
784
+ repaired: result.attempted === true,
785
+ noOp: result.noOp === true,
786
+ detail: result.detail,
787
+ ...(result.serviceLabel ? { serviceLabel: result.serviceLabel } : {}),
788
+ ...(result.serviceTarget ? { serviceTarget: result.serviceTarget } : {}),
789
+ verification: { ok: result.verify.ok },
790
+ ...(result.localVerify ? { localVerification: { ok: result.localVerify.ok } } : {}),
791
+ };
792
+ } catch (error) {
793
+ if (error instanceof AssistantPluginError) throw error;
794
+ throw new AssistantPluginError(
795
+ 'LOCAL_SYSTEM_RECOVERY_TUNNEL_REPAIR_FAILED',
796
+ bounded(error instanceof Error ? error.message : String(error), 2_000).content,
797
+ { retryable: false },
798
+ );
799
+ }
800
+ }
801
+
628
802
  function actions(): AssistantPluginActionDescriptor[] {
629
803
  const controllerRead = [{ resource: 'repo-state' as const, mode: 'read' as const }];
630
804
  const controllerWrite = [{ resource: 'repo-state' as const, mode: 'write' as const }];
@@ -639,6 +813,8 @@ function actions(): AssistantPluginActionDescriptor[] {
639
813
  { actionId: 'restart_user_launch_agent', title: 'Restart verified user LaunchAgent', description: 'Restart one loaded user LaunchAgent by exact label only after launchctl evidence contains the expected program identity.', readOnly: false, risk: 'workspace_write', confirmation: 'authorization', defaultTimeoutMs: 30_000, cancellable: true, idempotent: false, scopes: ['local-system.process'], resourceClaims: controllerWrite, argumentsSchema: { type: 'object', properties: { label: { type: 'string' }, expected_program_contains: { type: 'string' } }, required: ['label', 'expected_program_contains'], additionalProperties: false } },
640
814
  { actionId: 'stop_user_launch_agent', title: 'Stop verified user LaunchAgent', description: 'Boot out one exact loaded user LaunchAgent only after its launchd identity matches the expected program.', readOnly: false, risk: 'workspace_write', confirmation: 'authorization', defaultTimeoutMs: 30_000, cancellable: true, idempotent: true, scopes: ['local-system.process'], resourceClaims: controllerWrite, argumentsSchema: { type: 'object', properties: { label: { type: 'string' }, expected_program_contains: { type: 'string' } }, required: ['label', 'expected_program_contains'], additionalProperties: false } },
641
815
  { actionId: 'start_user_launch_agent', title: 'Start verified user LaunchAgent', description: 'Bootstrap or start one exact current-user LaunchAgent from ~/Library/LaunchAgents only after the installed plist matches the expected program identity.', readOnly: false, risk: 'workspace_write', confirmation: 'authorization', defaultTimeoutMs: 30_000, cancellable: true, idempotent: true, scopes: ['local-system.process'], resourceClaims: controllerWrite, argumentsSchema: { type: 'object', properties: { label: { type: 'string' }, expected_program_contains: { type: 'string' } }, required: ['label', 'expected_program_contains'], additionalProperties: false } },
816
+ { actionId: 'upgrade_standalone_recovery', title: 'Upgrade standalone Recovery', description: 'Upgrade the installed standalone Recovery from its configured primary Runtime source using the existing immutable Recovery release authority. No caller source path or command is accepted.', readOnly: false, risk: 'workspace_write', confirmation: 'authorization', defaultTimeoutMs: 240_000, cancellable: false, idempotent: true, scopes: ['local-system.process'], resourceClaims: controllerWrite, argumentsSchema: { type: 'object', properties: {}, additionalProperties: false } },
817
+ { actionId: 'repair_standalone_recovery_tunnel', title: 'Repair standalone Recovery tunnel', description: 'Repair only the installed standalone Recovery public tunnel using its existing configured tunnel identity and Recovery repair authority. No caller tunnel identity, path, executable, or command is accepted.', readOnly: false, risk: 'workspace_write', confirmation: 'authorization', defaultTimeoutMs: 60_000, cancellable: false, idempotent: true, scopes: ['local-system.process'], resourceClaims: controllerWrite, argumentsSchema: { type: 'object', properties: {}, additionalProperties: false } },
642
818
  { actionId: 'open_application', title: 'Open application', description: 'Open one macOS application by name or bundle id in the background without stealing foreground focus.', readOnly: false, risk: 'workspace_write', confirmation: 'authorization', defaultTimeoutMs: 30_000, cancellable: true, idempotent: false, scopes: ['local-system.open'], resourceClaims: controllerWrite, argumentsSchema: { type: 'object', properties: { app_name: { type: 'string' }, bundle_id: { type: 'string' } }, additionalProperties: false } },
643
819
  { actionId: 'list_targets', title: 'List filesystem targets', description: 'List active expiring local filesystem grants.', readOnly: true, risk: 'readonly', confirmation: 'none', defaultTimeoutMs: 10_000, cancellable: true, idempotent: true, scopes: ['local-system.files.read'], resourceClaims: controllerRead, argumentsSchema: { type: 'object', properties: {}, additionalProperties: false } },
644
820
  { actionId: 'authorize_target', title: 'Authorize filesystem target', description: 'Authorize an expiring filesystem target. By default, a path inside a Git project authorizes the whole project/repository root; use scope=directory only when intentionally granting a narrower directory.', readOnly: false, risk: 'workspace_write', confirmation: 'authorization', defaultTimeoutMs: 15_000, cancellable: true, idempotent: true, scopes: ['local-system.files.write'], resourceClaims: controllerWrite, argumentsSchema: { type: 'object', properties: { target_key: { type: 'string' }, root_path: { type: 'string' }, scope: { type: 'string', enum: ['auto', 'project', 'directory'] }, expires_in_minutes: { type: 'number' }, reason: { type: 'string' }, access: { type: 'string', enum: ['read_only', 'read_write'] } }, required: ['target_key', 'root_path', 'reason'], additionalProperties: false } },
@@ -692,6 +868,8 @@ function capabilities(): AssistantPluginCapability[] {
692
868
  return [
693
869
  { capabilityId: 'local-system-diagnostics', title: 'Local diagnostics', description: 'Inspect CPU, processes, and memory with bounded typed commands.', scopes: ['local-system.read'], actions: ['system_snapshot', 'process_detail'] },
694
870
  { capabilityId: 'local-system-process-control', title: 'Verified process lifecycle', description: 'Terminate one verified PID or stop/start/restart one verified macOS user LaunchAgent without exposing arbitrary shell execution.', scopes: ['local-system.process'], actions: ['terminate_process', 'restart_user_launch_agent', 'stop_user_launch_agent', 'start_user_launch_agent'] },
871
+ { capabilityId: 'local-system-recovery-upgrade', title: 'Managed standalone Recovery upgrade', description: 'Upgrade standalone Recovery only from its installed configured source through the immutable Recovery release and rollback authority.', scopes: ['local-system.process'], actions: ['upgrade_standalone_recovery'] },
872
+ { capabilityId: 'local-system-recovery-tunnel-repair', title: 'Managed standalone Recovery tunnel repair', description: 'Repair only the installed Recovery public tunnel through the existing Recovery tunnel repair authority when the Recovery transport itself is unreachable.', scopes: ['local-system.process'], actions: ['repair_standalone_recovery_tunnel'] },
695
873
  { capabilityId: 'local-system-open', title: 'Open local applications and files', description: 'Open applications and authorized files without arbitrary shell access.', scopes: ['local-system.open'], actions: ['open_application', 'reveal_in_finder', 'open_file'] },
696
874
  { capabilityId: 'local-system-files', title: 'Authorized local files', description: 'Use expiring target grants for bounded local file operations and typed-argv commands without repository registration.', scopes: ['local-system.files.read', 'local-system.files.write'], actions: ['list_targets', 'authorize_target', 'revoke_target', 'list_directory', 'read_text', 'write_text', 'delete_file', 'delete_empty_directory', 'initialize_git', 'execute_command', 'execute_project_script', 'create_directory', 'copy_file', 'move_file', 'rename_file'] },
697
875
  ];
@@ -747,6 +925,8 @@ export async function executeLocalSystemPluginAction(input: AssistantPluginActio
747
925
  case 'restart_user_launch_agent': return restartVerifiedUserLaunchAgent(input.args.label, input.args.expected_program_contains, input.controllerHome);
748
926
  case 'stop_user_launch_agent': return stopVerifiedUserLaunchAgent(input.args.label, input.args.expected_program_contains);
749
927
  case 'start_user_launch_agent': return startVerifiedUserLaunchAgent(input.args.label, input.args.expected_program_contains);
928
+ case 'upgrade_standalone_recovery': return await upgradeStandaloneRecovery(input.controllerHome);
929
+ case 'repair_standalone_recovery_tunnel': return await repairStandaloneRecoveryTunnel(input.controllerHome);
750
930
  case 'open_application': {
751
931
  const appName = optionalString(input.args, 'app_name');
752
932
  const bundleId = optionalString(input.args, 'bundle_id');
@@ -1,111 +1,21 @@
1
- import { randomUUID } from 'crypto';
2
- import { homedir } from 'os';
3
- import { join, resolve } from 'path';
4
- import { callExternalUnixSocket } from './external-unix-socket';
5
- import { AssistantPluginError } from './errors';
6
-
7
- const BROKER_PLUGIN_ID = 'desktop_operator';
8
- const BROKER_PROTOCOL_VERSION = '1.0';
9
- const BROWSER_AUTOMATION_CAPABILITY = 'macos_browser_automation.v1';
10
- const BROWSER_AUTOMATION_PROTOCOL_VERSION = 1;
11
- const MAX_RESPONSE_BYTES = 4 * 1_048_576;
12
- let testSocketPath: string | undefined;
13
-
14
- export function macOsCapabilityBrokerSocketPath(accountHome = process.env.HOME?.trim() || homedir()): string {
15
- return join(resolve(accountHome), 'Library', 'Caches', 'Forge', 'desktop-operator.sock');
16
- }
17
-
18
- export function setMacOsCapabilityBrokerSocketPathForTest(socketPath: string | undefined): void {
19
- testSocketPath = socketPath;
20
- }
21
-
22
- export function resetMacOsCapabilityBrokerSocketPathForTest(): void {
23
- testSocketPath = undefined;
24
- }
25
-
26
- function socketPath(): string {
27
- return testSocketPath ?? macOsCapabilityBrokerSocketPath();
28
- }
29
-
30
- function unavailable(error: AssistantPluginError, path: string): AssistantPluginError {
31
- if (!/^EXTERNAL_PLUGIN_(SOCKET_UNAVAILABLE|TIMEOUT|TRANSPORT_FAILED|PROTOCOL_ERROR)$/.test(error.code)) return error;
32
- return new AssistantPluginError(
33
- 'PLUGIN_MACOS_CAPABILITY_BROKER_UNAVAILABLE',
34
- `Stable Forge macOS capability broker is unavailable at ${path}. Install or restore Forge Desktop Operator instead of granting macOS permissions to Runtime or release-specific helpers.`,
35
- { retryable: true, details: { socketPath: path, providerPluginId: BROKER_PLUGIN_ID, causeCode: error.code } },
36
- );
37
- }
38
-
39
- export function validateMacOsCapabilityBrokerHandshake(
40
- handshake: Record<string, unknown>,
41
- requestedAction?: string,
42
- ): void {
43
- if (handshake.pluginId !== BROKER_PLUGIN_ID || handshake.protocolVersion !== BROKER_PROTOCOL_VERSION) {
44
- throw new AssistantPluginError(
45
- 'PLUGIN_MACOS_CAPABILITY_BROKER_IDENTITY_MISMATCH',
46
- 'Stable macOS capability broker returned an unexpected provider identity.',
47
- { retryable: false, details: { expectedPluginId: BROKER_PLUGIN_ID, expectedProtocolVersion: BROKER_PROTOCOL_VERSION } },
48
- );
49
- }
50
- const capabilities = Array.isArray(handshake.internalCapabilities)
51
- ? handshake.internalCapabilities.filter((entry): entry is string => typeof entry === 'string')
52
- : [];
53
- const actions = Array.isArray(handshake.browserAutomationActions)
54
- ? handshake.browserAutomationActions.filter((entry): entry is string => typeof entry === 'string')
55
- : [];
56
- const browserProtocolVersion = handshake.browserAutomationProtocolVersion;
57
- if (!capabilities.includes(BROWSER_AUTOMATION_CAPABILITY)
58
- || browserProtocolVersion !== BROWSER_AUTOMATION_PROTOCOL_VERSION
59
- || (requestedAction && !actions.includes(requestedAction))) {
60
- throw new AssistantPluginError(
61
- 'PLUGIN_MACOS_CAPABILITY_BROKER_CAPABILITY_UNSUPPORTED',
62
- requestedAction
63
- ? `Installed Forge Desktop Operator does not declare required browser automation action ${requestedAction}.`
64
- : 'Installed Forge Desktop Operator does not declare the required browser automation capability.',
65
- {
66
- retryable: false,
67
- details: {
68
- requiredCapability: BROWSER_AUTOMATION_CAPABILITY,
69
- requiredBrowserAutomationProtocolVersion: BROWSER_AUTOMATION_PROTOCOL_VERSION,
70
- ...(requestedAction ? { requiredAction: requestedAction } : {}),
71
- declaredCapability: capabilities.includes(BROWSER_AUTOMATION_CAPABILITY),
72
- declaredBrowserAutomationProtocolVersion: typeof browserProtocolVersion === 'number' ? browserProtocolVersion : null,
73
- declaredActionCount: actions.length,
74
- },
75
- },
76
- );
77
- }
78
- }
79
-
80
- async function verifyBrokerIdentity(path: string, timeoutMs: number, requestedAction?: string): Promise<void> {
81
- const handshake = await callExternalUnixSocket({
82
- socketPath: path,
83
- requestId: `macos-broker-handshake:${randomUUID()}`,
84
- method: 'handshake',
85
- timeoutMs: Math.min(timeoutMs, 2_000),
86
- maxResponseBytes: 64 * 1024,
87
- });
88
- validateMacOsCapabilityBrokerHandshake(handshake, requestedAction);
89
- }
1
+ /** @deprecated C0 compatibility shim. Browser code must consume the provider-neutral Computer boundary. */
2
+ import type { ComputerBrowserAutomationRequest } from '../../../packages/protocols/computer/index';
3
+ import {
4
+ desktopOperatorComputerSocketPath,
5
+ resetDesktopOperatorComputerSocketPathForTest,
6
+ setDesktopOperatorComputerSocketPathForTest,
7
+ validateDesktopOperatorComputerHandshake,
8
+ } from '../../../adapters/computer/desktop-operator-provider';
9
+ import { executeRuntimeComputerBrowserAutomation } from '../root/computer-composition';
10
+
11
+ export const macOsCapabilityBrokerSocketPath = desktopOperatorComputerSocketPath;
12
+ export const resetMacOsCapabilityBrokerSocketPathForTest = resetDesktopOperatorComputerSocketPathForTest;
13
+ export const setMacOsCapabilityBrokerSocketPathForTest = setDesktopOperatorComputerSocketPathForTest;
14
+ export const validateMacOsCapabilityBrokerHandshake = validateDesktopOperatorComputerHandshake;
90
15
 
91
16
  export async function callMacOsCapabilityBroker(
92
17
  params: Record<string, unknown>,
93
18
  timeoutMs: number,
94
19
  ): Promise<Record<string, unknown>> {
95
- const path = socketPath();
96
- try {
97
- const requestedAction = typeof params.action === 'string' ? params.action : undefined;
98
- await verifyBrokerIdentity(path, timeoutMs, requestedAction);
99
- return await callExternalUnixSocket({
100
- socketPath: path,
101
- requestId: `macos-broker:${randomUUID()}`,
102
- method: 'macos_browser_automation',
103
- params,
104
- timeoutMs,
105
- maxResponseBytes: MAX_RESPONSE_BYTES,
106
- });
107
- } catch (error) {
108
- if (error instanceof AssistantPluginError) throw unavailable(error, path);
109
- throw error;
110
- }
20
+ return await executeRuntimeComputerBrowserAutomation(params as unknown as ComputerBrowserAutomationRequest, timeoutMs);
111
21
  }