@moretea-labs/forge 1.7.1 → 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 +39 -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 -1585
  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 +417 -100
  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 +267 -16
  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 -6651
  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 +86 -18
  609. package/src/runtime/root/package-runtime-service.ts +63 -86
  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,10 +1,9 @@
1
- import { spawnSync } from 'child_process';
2
- import { existsSync } from 'fs';
1
+ import { spawn } from 'child_process';
3
2
  import { createServer } from 'net';
4
- import { homedir } from 'os';
5
- import { join, resolve } from 'path';
3
+ import { resolve } from 'path';
6
4
  import { pathToFileURL } from 'url';
7
5
  import type { BrowserConsultInput, NativeBrowserChannel, PromptBundle } from './types';
6
+ import { describeNativeBrowserProduct, discoverNativeBrowserProduct } from '../../runtime/platform/browser-product-discovery';
8
7
 
9
8
  export interface NativeProviderResult {
10
9
  status: 'completed' | 'failed' | 'incomplete_capture';
@@ -46,25 +45,6 @@ const SEND_BUTTON_SELECTORS = [
46
45
  const ASSISTANT_SELECTOR = '[data-message-author-role="assistant"]';
47
46
  const STABLE_CAPTURE_MS = 5000;
48
47
 
49
- const CHANNEL_APPS: Record<NativeBrowserChannel, { appName: string; executable: string }> = {
50
- chrome: {
51
- appName: 'Google Chrome',
52
- executable: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
53
- },
54
- 'chrome-beta': {
55
- appName: 'Google Chrome Beta',
56
- executable: '/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta',
57
- },
58
- 'chrome-dev': {
59
- appName: 'Google Chrome Dev',
60
- executable: '/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev',
61
- },
62
- 'chrome-canary': {
63
- appName: 'Google Chrome Canary',
64
- executable: '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',
65
- },
66
- };
67
-
68
48
  interface CdpConnection {
69
49
  send(method: string, params?: Record<string, unknown>, sessionId?: string): Promise<any>;
70
50
  close(): void;
@@ -74,10 +54,6 @@ function browserChannel(input?: NativeBrowserChannel): NativeBrowserChannel {
74
54
  return input ?? 'chrome';
75
55
  }
76
56
 
77
- function chromeExecutable(channel: NativeBrowserChannel): string {
78
- return CHANNEL_APPS[channel].executable;
79
- }
80
-
81
57
  function chromeProfileArgs(profileDir: string, profileDirectory?: string): string[] {
82
58
  return [
83
59
  `--user-data-dir=${profileDir}`,
@@ -90,41 +66,13 @@ function normalizeComparablePath(path: string): string {
90
66
  return process.platform === 'win32' ? normalized.toLowerCase() : normalized;
91
67
  }
92
68
 
93
- function defaultChromeUserDataDir(channel: NativeBrowserChannel): string | undefined {
94
- if (process.platform === 'darwin') {
95
- const base = join(homedir(), 'Library/Application Support/Google');
96
- if (channel === 'chrome') return join(base, 'Chrome');
97
- if (channel === 'chrome-beta') return join(base, 'Chrome Beta');
98
- if (channel === 'chrome-dev') return join(base, 'Chrome Dev');
99
- return join(base, 'Chrome Canary');
100
- }
101
-
102
- if (process.platform === 'win32') {
103
- const base = join(process.env.LOCALAPPDATA ?? join(homedir(), 'AppData/Local'), 'Google');
104
- if (channel === 'chrome') return join(base, 'Chrome/User Data');
105
- if (channel === 'chrome-beta') return join(base, 'Chrome Beta/User Data');
106
- if (channel === 'chrome-dev') return join(base, 'Chrome Dev/User Data');
107
- return join(base, 'Chrome SxS/User Data');
108
- }
109
-
110
- if (process.platform === 'linux') {
111
- const base = process.env.XDG_CONFIG_HOME ?? join(homedir(), '.config');
112
- if (channel === 'chrome') return join(base, 'google-chrome');
113
- if (channel === 'chrome-beta') return join(base, 'google-chrome-beta');
114
- if (channel === 'chrome-dev') return join(base, 'google-chrome-unstable');
115
- return join(base, 'google-chrome-unstable');
116
- }
117
-
118
- return undefined;
119
- }
120
-
121
69
  export function nativeDebuggingBlockedByDefaultProfile(profileDir: string, channel: NativeBrowserChannel): boolean {
122
- const defaultDir = defaultChromeUserDataDir(channel);
70
+ const defaultDir = describeNativeBrowserProduct({ channel })?.defaultUserDataDir;
123
71
  return defaultDir !== undefined && normalizeComparablePath(profileDir) === normalizeComparablePath(defaultDir);
124
72
  }
125
73
 
126
74
  function defaultProfileCdpBlockedError(channel: NativeBrowserChannel, profileDir: string, profileDirectory?: string): NonNullable<NativeProviderResult['error']> {
127
- const app = CHANNEL_APPS[channel].appName;
75
+ const app = describeNativeBrowserProduct({ channel })?.appName ?? channel;
128
76
  return {
129
77
  code: 'NATIVE_DEFAULT_PROFILE_CDP_BLOCKED',
130
78
  message: `${app} blocks remote debugging against the default Chrome data directory: ${profileDir}${profileDirectory ? ` (${profileDirectory})` : ''}`,
@@ -133,7 +81,7 @@ function defaultProfileCdpBlockedError(channel: NativeBrowserChannel, profileDir
133
81
  }
134
82
 
135
83
  export async function nativeProviderAvailable(): Promise<boolean> {
136
- return process.platform === 'darwin' && existsSync(chromeExecutable('chrome'));
84
+ return discoverNativeBrowserProduct({ channel: 'chrome' }) !== undefined;
137
85
  }
138
86
 
139
87
  function conversationUrl(url: string): string | undefined {
@@ -175,7 +123,7 @@ async function waitForCdp(port: number, timeoutMs: number): Promise<{ webSocketD
175
123
  } catch (_error) {
176
124
  // Chrome may need a moment to expose the DevTools endpoint.
177
125
  }
178
- await Bun.sleep(250);
126
+ await new Promise<void>((resolveSleep) => setTimeout(resolveSleep, 250));
179
127
  }
180
128
  throw new Error(`Chrome CDP endpoint did not become ready on port ${port}`);
181
129
  }
@@ -220,30 +168,22 @@ function connectCdp(webSocketUrl: string): Promise<CdpConnection> {
220
168
  }
221
169
 
222
170
  export function openNativeBrowserPage(channel: NativeBrowserChannel, profileDir: string, url: string, profileDirectory?: string): void {
223
- const app = CHANNEL_APPS[channel];
224
- if (!existsSync(app.executable)) throw new Error(`${app.appName} is not installed at ${app.executable}`);
171
+ const product = discoverNativeBrowserProduct({ channel });
172
+ if (!product) throw new Error(`Browser provider ${channel} is not installed or registered on this host`);
225
173
  const args = [
226
- '-na',
227
- app.appName,
228
- '--args',
229
174
  ...chromeProfileArgs(profileDir, profileDirectory),
230
175
  '--no-first-run',
231
176
  '--no-default-browser-check',
232
177
  url.startsWith('/') ? pathToFileURL(url).toString() : url,
233
178
  ];
234
- const result = spawnSync('open', args, { encoding: 'utf-8' });
235
- if (result.status !== 0) {
236
- throw new Error((result.stderr || result.stdout || `failed to open ${app.appName}`).trim());
237
- }
179
+ const child = spawn(product.executable, args, { detached: true, stdio: 'ignore' });
180
+ child.once('error', () => undefined);
181
+ child.unref();
238
182
  }
239
-
240
183
  async function launchChrome(channel: NativeBrowserChannel, profileDir: string, port: number, headless: boolean, url = 'about:blank', profileDirectory?: string): Promise<void> {
241
- const app = CHANNEL_APPS[channel];
242
- if (!existsSync(app.executable)) throw new Error(`${app.appName} is not installed at ${app.executable}`);
184
+ const product = discoverNativeBrowserProduct({ channel });
185
+ if (!product) throw new Error(`Browser provider ${channel} is not installed or registered on this host`);
243
186
  const args = [
244
- '-na',
245
- app.appName,
246
- '--args',
247
187
  `--remote-debugging-port=${port}`,
248
188
  '--remote-allow-origins=*',
249
189
  ...chromeProfileArgs(profileDir, profileDirectory),
@@ -252,12 +192,13 @@ async function launchChrome(channel: NativeBrowserChannel, profileDir: string, p
252
192
  ...(headless ? ['--headless=new'] : []),
253
193
  url,
254
194
  ];
255
- const result = spawnSync('open', args, { encoding: 'utf-8' });
256
- if (result.status !== 0) {
257
- throw new Error((result.stderr || result.stdout || `failed to open ${app.appName}`).trim());
258
- }
195
+ const child = spawn(product.executable, args, { detached: true, stdio: 'ignore' });
196
+ await new Promise<void>((resolveLaunch, rejectLaunch) => {
197
+ child.once('spawn', resolveLaunch);
198
+ child.once('error', rejectLaunch);
199
+ });
200
+ child.unref();
259
201
  }
260
-
261
202
  function browserEval(body: string): string {
262
203
  return `(() => { try { ${body} } catch (error) { return { ok: false, error: String(error), url: location.href, title: document.title }; } })()`;
263
204
  }
@@ -276,7 +217,7 @@ async function waitFor<T>(deadlineMs: number, fn: () => Promise<T>, accept: (val
276
217
  while (Date.now() < deadline) {
277
218
  const value = await fn();
278
219
  if (accept(value)) return value;
279
- await Bun.sleep(500);
220
+ await new Promise<void>((resolveSleep) => setTimeout(resolveSleep, 500));
280
221
  }
281
222
  return null;
282
223
  }
@@ -356,7 +297,7 @@ export async function checkNativeChatgptSession(input: {
356
297
  error: {
357
298
  code: 'NATIVE_SESSION_CHECK_FAILED',
358
299
  message: error instanceof Error ? error.message : String(error),
359
- recovery: `Verify Google Chrome is installed for channel "${channel}", close other Chrome windows using this profile, then retry.`,
300
+ recovery: `Verify a Chromium provider is installed or configure FORGE_BROWSER_EXECUTABLE for channel "${channel}", close other browser windows using this profile, then retry.`,
360
301
  },
361
302
  };
362
303
  } finally {
@@ -417,7 +358,7 @@ async function waitForStableAssistantText(connection: CdpConnection, sessionId:
417
358
  return { text, stable: true };
418
359
  }
419
360
  }
420
- await Bun.sleep(500);
361
+ await new Promise<void>((resolveSleep) => setTimeout(resolveSleep, 500));
421
362
  }
422
363
  return { text: latest, stable: false };
423
364
  }
@@ -539,7 +480,7 @@ export async function runNativeProvider(input: BrowserConsultInput, bundle: Prom
539
480
  error: {
540
481
  code: 'NATIVE_PROVIDER_FAILED',
541
482
  message: error instanceof Error ? error.message : String(error),
542
- recovery: `Verify Google Chrome is installed for channel "${channel}", close other Chrome windows using this profile, then retry.`,
483
+ recovery: `Verify a Chromium provider is installed or configure FORGE_BROWSER_EXECUTABLE for channel "${channel}", close other browser windows using this profile, then retry.`,
543
484
  },
544
485
  };
545
486
  } finally {
@@ -3,6 +3,7 @@ import { accessSync, constants, existsSync, lstatSync, mkdirSync, mkdtempSync, r
3
3
  import { tmpdir } from 'os';
4
4
  import { isAbsolute, join, resolve } from 'path';
5
5
  import type { BrowserConsultInput, BrowserImportedArtifact, PromptBundle } from './types';
6
+ import { discoverExecutable } from '../../runtime/platform/executable-discovery';
6
7
 
7
8
  export interface OracleProviderResult {
8
9
  status: 'completed' | 'recoverable' | 'failed';
@@ -64,7 +65,8 @@ function resolveConfiguredOracleBin(value: string, repoRoot: string): string | u
64
65
  if (!hasPathSeparator) {
65
66
  const repoRelative = join(repoRoot, value);
66
67
  if (existsSync(repoRelative)) return repoRelative;
67
- return Bun.which(value) ?? undefined;
68
+ const discovered = discoverExecutable({ id: 'oracle', candidates: [value] });
69
+ return discovered.status === 'ready' ? discovered.executable : undefined;
68
70
  }
69
71
  const candidate = isAbsolute(value) ? value : resolve(repoRoot, value);
70
72
  return existsSync(candidate) ? candidate : undefined;
@@ -98,8 +100,8 @@ export function resolveOracleBin(input: Pick<BrowserConsultInput, 'repoRoot' | '
98
100
  }
99
101
  const repoLocal = join(input.repoRoot, 'node_modules', '.bin', 'oracle');
100
102
  if (existsSync(repoLocal)) return { binary: repoLocal, source: 'node_modules/.bin' };
101
- const onPath = Bun.which('oracle');
102
- if (onPath) return { binary: onPath, source: 'PATH' };
103
+ const onPath = discoverExecutable({ id: 'oracle', candidates: ['oracle'] });
104
+ if (onPath.status === 'ready' && onPath.executable) return { binary: onPath.executable, source: 'PATH' };
103
105
  return {
104
106
  source: 'missing',
105
107
  error: {
@@ -26,6 +26,7 @@ export interface BrowserConsultInput {
26
26
  model?: string;
27
27
  thinking?: ThinkingLevel;
28
28
  provider?: BrowserProviderName;
29
+ dispatchOnly?: boolean;
29
30
  chatgptUrl?: string;
30
31
  timeoutMs?: number;
31
32
  heartbeatSeconds?: number;
@@ -0,0 +1,334 @@
1
+ import { resolveControllerHome, controllerSystemRoot } from '../repositories/controller-home';
2
+ import {
3
+ createBootstrapControlApi,
4
+ type BootstrapControlApi,
5
+ type BootstrapAction,
6
+ resolveBootstrapCapabilityProviders,
7
+ type BootstrapBlocker,
8
+ type BootstrapCapabilityProviderResolution,
9
+ type BootstrapDesiredState,
10
+ type BootstrapEvaluation,
11
+ type BootstrapObservation,
12
+ type BootstrapSnapshot,
13
+ type BootstrapStep,
14
+ } from '../../runtime/control-plane/bootstrap';
15
+ import {
16
+ detectSetupPlatform,
17
+ readSetupProfile,
18
+ resolveControllerGuidance,
19
+ resolveRuntimeGuidance,
20
+ resolveTunnelGuidance,
21
+ setupNeedsRemoteAccess,
22
+ type ControllerGuidance,
23
+ type RuntimeGuidance,
24
+ type SetupPlatformSnapshot,
25
+ type SetupProfile,
26
+ type SetupProfileOptions,
27
+ type TunnelGuidance,
28
+ } from './setup-profile';
29
+ import { listControllerPluginManifests } from '../../runtime/plugins/store';
30
+ import { officialPluginCatalogItems } from './plugin';
31
+ import { bootstrapWslWindowsBridgeBrowser, observeWslWindowsBridgeBrowser } from '../chatgpt-browser/bridge-provider';
32
+
33
+ export interface SetupBridgeGuidance {
34
+ required: boolean;
35
+ ready: boolean;
36
+ automatic: boolean;
37
+ summary: string;
38
+ }
39
+
40
+ export interface SetupBootstrapDependencies {
41
+ capabilities(intents: readonly string[], options: { controllerHome: string; platform: SetupPlatformSnapshot }): BootstrapCapabilityProviderResolution[];
42
+ bridge(profile: SetupProfile | undefined, platform: SetupPlatformSnapshot, options: { controllerHome: string }): SetupBridgeGuidance;
43
+ controller(profile: SetupProfile | undefined, options: { controllerHome?: string; home?: string }): ControllerGuidance | undefined;
44
+ runtime(profile: SetupProfile | undefined, options: { controllerHome?: string }): RuntimeGuidance | undefined;
45
+ tunnel(profile: SetupProfile | undefined, platform: SetupPlatformSnapshot, options: { controllerHome?: string; env?: NodeJS.ProcessEnv }): TunnelGuidance;
46
+ }
47
+
48
+ export interface SetupBootstrapOptions extends SetupProfileOptions {
49
+ controllerHome?: string;
50
+ accountHome?: string;
51
+ profile?: SetupProfile;
52
+ platform?: SetupPlatformSnapshot;
53
+ capabilities?: string[];
54
+ dependencies?: Partial<SetupBootstrapDependencies>;
55
+ }
56
+
57
+ function setupBridgeRoot(controllerHome: string): string {
58
+ return controllerSystemRoot(controllerHome);
59
+ }
60
+
61
+ const DEFAULT_DEPENDENCIES: SetupBootstrapDependencies = {
62
+ capabilities: (intents, options) => {
63
+ if (intents.length === 0) return [];
64
+ const installedManifests = listControllerPluginManifests(options.controllerHome, { preferStored: true });
65
+ const catalog = officialPluginCatalogItems(options.platform.platform);
66
+ return resolveBootstrapCapabilityProviders({ capabilityIntents: intents, installedManifests, catalog });
67
+ },
68
+ bridge: (profile, platform, options) => {
69
+ if (!profile?.controllers.includes('chatgpt') || platform.environment !== 'wsl2') {
70
+ return { required: false, ready: true, automatic: false, summary: 'Windows ChatGPT bridge browser is not required for this setup.' };
71
+ }
72
+ const bridgeRoot = setupBridgeRoot(options.controllerHome);
73
+ const readiness = observeWslWindowsBridgeBrowser(bridgeRoot, { platform: 'linux', wslDistroName: 'ForgeSetup' });
74
+ return { required: readiness.required, ready: readiness.ready, automatic: readiness.automatic, summary: readiness.summary };
75
+ },
76
+ controller: resolveControllerGuidance,
77
+ runtime: resolveRuntimeGuidance,
78
+ tunnel: resolveTunnelGuidance,
79
+ };
80
+
81
+ function desiredState(profile: SetupProfile | undefined, capabilities: readonly string[] = []): BootstrapDesiredState {
82
+ const primaryController = profile?.primaryController ?? 'chatgpt';
83
+ const controllers = profile?.controllers ?? [primaryController];
84
+ const remote = setupNeedsRemoteAccess(profile ?? { schemaVersion: 1, primaryController, controllers, tunnel: { provider: 'auto' }, createdAt: '', updatedAt: '' });
85
+ const provider = profile?.tunnel.provider ?? 'auto';
86
+ const preferredTransport = !remote || provider === 'none'
87
+ ? 'none'
88
+ : provider === 'openai' || provider === 'auto'
89
+ ? 'openai-secure-tunnel'
90
+ : 'https-endpoint';
91
+ return {
92
+ schemaVersion: 1,
93
+ primaryController,
94
+ controllers,
95
+ connectivity: {
96
+ mode: remote ? 'remote' : 'local',
97
+ preferredTransport,
98
+ ...(profile?.tunnel.endpoint ? { endpoint: profile.tunnel.endpoint } : {}),
99
+ ...(profile?.tunnel.tunnelId ? { tunnelId: profile.tunnel.tunnelId } : {}),
100
+ },
101
+ capabilityIntents: [...new Set([...(profile?.capabilityIntents ?? []), ...capabilities])],
102
+ };
103
+ }
104
+
105
+ function actionFromGuidance(input: {
106
+ id: string;
107
+ kind: BootstrapAction['kind'];
108
+ title: string;
109
+ detail: string;
110
+ command?: string;
111
+ owner?: BootstrapAction['owner'];
112
+ }): BootstrapAction {
113
+ return {
114
+ id: input.id,
115
+ kind: input.kind,
116
+ owner: input.owner ?? 'forge',
117
+ summary: `${input.title}: ${input.detail}`,
118
+ ...(input.command ? { command: input.command } : {}),
119
+ verification: 'forge setup next',
120
+ };
121
+ }
122
+
123
+ function blockerFor(stepId: string, code: string, action: BootstrapAction, summary: string): BootstrapBlocker {
124
+ return {
125
+ code,
126
+ kind: action.owner === 'user' ? 'user_action' : 'automatic_retry',
127
+ stepId,
128
+ summary,
129
+ actionIds: [action.id],
130
+ };
131
+ }
132
+
133
+ function step(input: {
134
+ id: string;
135
+ label: string;
136
+ state: BootstrapStep['state'];
137
+ dependsOn?: string[];
138
+ observation?: BootstrapObservation;
139
+ blocker?: BootstrapBlocker;
140
+ action?: BootstrapAction;
141
+ }): BootstrapStep {
142
+ return {
143
+ id: input.id,
144
+ label: input.label,
145
+ state: input.state,
146
+ dependsOn: input.dependsOn ?? [],
147
+ observationIds: input.observation ? [input.observation.id] : [],
148
+ blockerCodes: input.blocker ? [input.blocker.code] : [],
149
+ actionIds: input.action ? [input.action.id] : [],
150
+ };
151
+ }
152
+
153
+ function userOwnsTunnelGuidance(guidance: TunnelGuidance): boolean {
154
+ return guidance.title === 'Create an OpenAI Secure MCP Tunnel'
155
+ || guidance.title === 'Install OpenAI tunnel-client'
156
+ || guidance.title === 'Record existing HTTPS endpoint'
157
+ || guidance.title === 'Create a stable Cloudflare Tunnel'
158
+ || guidance.title === 'Install Cloudflare Tunnel'
159
+ || guidance.title === 'Install Tailscale';
160
+ }
161
+
162
+ export function observeSetupBootstrap(options: SetupBootstrapOptions = {}): BootstrapEvaluation {
163
+ const controllerHome = resolveControllerHome(options.controllerHome);
164
+ const profile = options.profile ?? readSetupProfile(options);
165
+ const platform = options.platform ?? detectSetupPlatform({ env: options.env });
166
+ const dependencies = { ...DEFAULT_DEPENDENCIES, ...options.dependencies };
167
+ const observedAt = (options.now ?? (() => new Date()))().toISOString();
168
+ const observations: BootstrapObservation[] = [];
169
+ const actions: BootstrapAction[] = [];
170
+ const blockers: BootstrapBlocker[] = [];
171
+ const steps: BootstrapStep[] = [];
172
+
173
+ const profileObservation: BootstrapObservation = profile
174
+ ? { id: 'setup.profile', component: 'platform', status: 'ready', summary: `Setup profile selects ${profile.primaryController} as primary controller.`, observedAt }
175
+ : { id: 'setup.profile', component: 'platform', status: 'missing', summary: 'No Forge setup profile is configured yet.', reasonCodes: ['SETUP_PROFILE_MISSING'], observedAt };
176
+ observations.push(profileObservation);
177
+ if (!profile) {
178
+ const action = actionFromGuidance({ id: 'controller.select', kind: 'configure', title: 'Configure Forge controller', detail: 'Create the instance-level setup profile.', command: 'forge setup configure --controller chatgpt' });
179
+ const blocker = blockerFor('profile', 'BOOTSTRAP_SETUP_PROFILE_MISSING', action, profileObservation.summary);
180
+ actions.push(action); blockers.push(blocker);
181
+ steps.push(step({ id: 'profile', label: 'Desired setup profile', state: 'blocked', observation: profileObservation, blocker, action }));
182
+ } else {
183
+ steps.push(step({ id: 'profile', label: 'Desired setup profile', state: 'ready', observation: profileObservation }));
184
+ }
185
+
186
+ const controllerGuidance = profile ? dependencies.controller(profile, { controllerHome, home: options.accountHome }) : undefined;
187
+ const controllerObservation: BootstrapObservation = !profile
188
+ ? { id: 'controller.primary', component: 'controller', status: 'unknown', summary: 'Controller readiness waits for setup profile selection.', observedAt }
189
+ : controllerGuidance && !controllerGuidance.ready
190
+ ? { id: 'controller.primary', component: 'controller', status: 'blocked', summary: `${controllerGuidance.title}: ${controllerGuidance.detail}`, provider: controllerGuidance.controller, reasonCodes: ['CONTROLLER_NOT_READY'], observedAt }
191
+ : { id: 'controller.primary', component: 'controller', status: 'ready', summary: 'Configured controller set is ready.', observedAt };
192
+ observations.push(controllerObservation);
193
+ if (!profile) {
194
+ steps.push(step({ id: 'controller', label: 'Controller connectivity', state: 'pending', dependsOn: ['profile'], observation: controllerObservation }));
195
+ } else if (controllerGuidance && !controllerGuidance.ready) {
196
+ const owner: BootstrapAction['owner'] = controllerGuidance.command ? 'forge' : 'user';
197
+ const action = actionFromGuidance({ id: `controller.${controllerGuidance.controller}.configure`, kind: controllerGuidance.command ? 'configure' : 'authenticate', title: controllerGuidance.title, detail: controllerGuidance.detail, command: controllerGuidance.command, owner });
198
+ const blocker = blockerFor('controller', `BOOTSTRAP_CONTROLLER_${controllerGuidance.controller.toUpperCase()}_NOT_READY`, action, controllerObservation.summary);
199
+ actions.push(action); blockers.push(blocker);
200
+ steps.push(step({ id: 'controller', label: 'Controller connectivity', state: 'blocked', dependsOn: ['profile'], observation: controllerObservation, blocker, action }));
201
+ } else {
202
+ steps.push(step({ id: 'controller', label: 'Controller connectivity', state: 'ready', dependsOn: ['profile'], observation: controllerObservation }));
203
+ }
204
+
205
+ const runtimeGuidance = profile ? dependencies.runtime(profile, { controllerHome }) : undefined;
206
+ const runtimeRequired = Boolean(profile && setupNeedsRemoteAccess(profile));
207
+ const runtimeObservation: BootstrapObservation = !profile
208
+ ? { id: 'runtime.package', component: 'runtime', status: 'unknown', summary: 'Runtime readiness waits for setup profile selection.', observedAt }
209
+ : !runtimeRequired
210
+ ? { id: 'runtime.package', component: 'runtime', status: 'ready', summary: 'Packaged Runtime is not required by the configured local-only controller set.', observedAt }
211
+ : runtimeGuidance?.ready
212
+ ? { id: 'runtime.package', component: 'runtime', status: 'ready', summary: runtimeGuidance.detail, observedAt }
213
+ : { id: 'runtime.package', component: 'runtime', status: 'blocked', summary: runtimeGuidance ? `${runtimeGuidance.title}: ${runtimeGuidance.detail}` : 'Packaged Runtime is not ready.', reasonCodes: ['RUNTIME_NOT_READY'], observedAt };
214
+ observations.push(runtimeObservation);
215
+ if (!profile) {
216
+ steps.push(step({ id: 'runtime', label: 'Packaged Runtime', state: 'pending', dependsOn: ['controller'], observation: runtimeObservation }));
217
+ } else if (!runtimeRequired || runtimeGuidance?.ready) {
218
+ steps.push(step({ id: 'runtime', label: 'Packaged Runtime', state: runtimeRequired ? 'ready' : 'skipped', dependsOn: ['controller'], observation: runtimeObservation }));
219
+ } else {
220
+ const action = actionFromGuidance({ id: 'runtime.package.install', kind: 'repair', title: runtimeGuidance?.title ?? 'Repair packaged Runtime', detail: runtimeGuidance?.detail ?? 'Install or repair the packaged Runtime.', command: runtimeGuidance?.command });
221
+ const blocker = blockerFor('runtime', 'BOOTSTRAP_RUNTIME_NOT_READY', action, runtimeObservation.summary);
222
+ actions.push(action); blockers.push(blocker);
223
+ steps.push(step({ id: 'runtime', label: 'Packaged Runtime', state: 'blocked', dependsOn: ['controller'], observation: runtimeObservation, blocker, action }));
224
+ }
225
+
226
+ const tunnelGuidance = profile ? dependencies.tunnel(profile, platform, { controllerHome, env: options.env }) : undefined;
227
+ const connectivityObservation: BootstrapObservation = !profile
228
+ ? { id: 'connectivity.controller', component: 'connectivity', status: 'unknown', summary: 'Connectivity policy waits for setup profile selection.', observedAt }
229
+ : tunnelGuidance?.ready
230
+ ? { id: 'connectivity.controller', component: 'connectivity', status: 'ready', summary: tunnelGuidance.detail, provider: tunnelGuidance.provider, endpoint: profile.tunnel.endpoint, observedAt }
231
+ : { id: 'connectivity.controller', component: 'connectivity', status: 'blocked', summary: tunnelGuidance ? `${tunnelGuidance.title}: ${tunnelGuidance.detail}` : 'Controller connectivity is not ready.', provider: tunnelGuidance?.provider, reasonCodes: ['CONNECTIVITY_NOT_READY'], observedAt };
232
+ observations.push(connectivityObservation);
233
+ if (!profile) {
234
+ steps.push(step({ id: 'connectivity', label: 'Controller transport', state: 'pending', dependsOn: ['runtime'], observation: connectivityObservation }));
235
+ } else if (tunnelGuidance?.ready) {
236
+ steps.push(step({ id: 'connectivity', label: 'Controller transport', state: setupNeedsRemoteAccess(profile) ? 'ready' : 'skipped', dependsOn: ['runtime'], observation: connectivityObservation }));
237
+ } else {
238
+ const userOwned = tunnelGuidance ? userOwnsTunnelGuidance(tunnelGuidance) : true;
239
+ const action = actionFromGuidance({ id: `tunnel.${tunnelGuidance?.provider ?? 'unknown'}.configure`, kind: userOwned ? 'authenticate' : 'reconnect', title: tunnelGuidance?.title ?? 'Configure controller transport', detail: tunnelGuidance?.detail ?? 'Configure controller transport.', command: tunnelGuidance?.command, owner: userOwned ? 'user' : 'forge' });
240
+ const blocker = blockerFor('connectivity', `BOOTSTRAP_CONNECTIVITY_${(tunnelGuidance?.provider ?? 'UNKNOWN').toUpperCase().replaceAll('-', '_')}_NOT_READY`, action, connectivityObservation.summary);
241
+ actions.push(action); blockers.push(blocker);
242
+ steps.push(step({ id: 'connectivity', label: 'Controller transport', state: 'blocked', dependsOn: ['runtime'], observation: connectivityObservation, blocker, action }));
243
+ }
244
+
245
+ const bridgeGuidance = dependencies.bridge(profile, platform, { controllerHome });
246
+ const bridgeObservation: BootstrapObservation = !bridgeGuidance.required
247
+ ? { id: 'provider.chatgpt.wsl-bridge', component: 'provider', status: 'ready', summary: bridgeGuidance.summary, observedAt }
248
+ : bridgeGuidance.ready
249
+ ? { id: 'provider.chatgpt.wsl-bridge', component: 'provider', status: 'ready', summary: bridgeGuidance.summary, provider: 'controlled-windows-chromium', observedAt }
250
+ : { id: 'provider.chatgpt.wsl-bridge', component: 'provider', status: 'missing', summary: bridgeGuidance.summary, provider: 'controlled-windows-chromium', reasonCodes: ['CHATGPT_WSL_BRIDGE_BROWSER_NOT_READY'], observedAt };
251
+ observations.push(bridgeObservation);
252
+ if (!bridgeGuidance.required) {
253
+ steps.push(step({ id: 'chatgpt-wsl-bridge', label: 'WSL ChatGPT bridge browser', state: 'skipped', dependsOn: ['connectivity'], observation: bridgeObservation }));
254
+ } else if (bridgeGuidance.ready) {
255
+ steps.push(step({ id: 'chatgpt-wsl-bridge', label: 'WSL ChatGPT bridge browser', state: 'ready', dependsOn: ['connectivity'], observation: bridgeObservation }));
256
+ } else {
257
+ const action: BootstrapAction = bridgeGuidance.automatic
258
+ ? { id: 'chatgpt.bridge.bootstrap', kind: 'install', owner: 'forge', summary: bridgeGuidance.summary, command: 'forge setup bridge-browser', verification: 'forge setup next' }
259
+ : { id: 'chatgpt.bridge.user-action', kind: 'install', owner: 'user', summary: bridgeGuidance.summary, verification: 'forge setup next' };
260
+ const blocker = blockerFor('chatgpt-wsl-bridge', 'BOOTSTRAP_CHATGPT_WSL_BRIDGE_BROWSER_NOT_READY', action, bridgeGuidance.summary);
261
+ actions.push(action); blockers.push(blocker);
262
+ steps.push(step({ id: 'chatgpt-wsl-bridge', label: 'WSL ChatGPT bridge browser', state: 'blocked', dependsOn: ['connectivity'], observation: bridgeObservation, blocker, action }));
263
+ }
264
+
265
+ const desired = desiredState(profile, options.capabilities);
266
+ for (const resolution of dependencies.capabilities(desired.capabilityIntents, { controllerHome, platform })) {
267
+ const safeCapabilityId = resolution.capabilityId.replace(/[^a-zA-Z0-9_.-]+/g, '-');
268
+ const observation: BootstrapObservation = {
269
+ id: `capability.${safeCapabilityId}`,
270
+ component: 'plugin',
271
+ status: resolution.status === 'ready' ? 'ready' : resolution.status === 'unsupported' ? 'unsupported' : 'degraded',
272
+ summary: resolution.summary,
273
+ ...(resolution.providerId ? { provider: resolution.providerId } : {}),
274
+ ...(resolution.status === 'ready' ? {} : { reasonCodes: [`CAPABILITY_${resolution.status.toUpperCase()}`] }),
275
+ observedAt,
276
+ };
277
+ observations.push(observation);
278
+ const stepId = `capability.${safeCapabilityId}`;
279
+ if (resolution.status === 'ready') {
280
+ steps.push(step({ id: stepId, label: `Capability ${resolution.capabilityId}`, state: 'ready', dependsOn: ['connectivity'], observation }));
281
+ continue;
282
+ }
283
+ if (resolution.status === 'unsupported' || !resolution.providerId) {
284
+ const blocker: BootstrapBlocker = {
285
+ code: `BOOTSTRAP_CAPABILITY_${safeCapabilityId.toUpperCase().replaceAll('.', '_').replaceAll('-', '_')}_UNSUPPORTED`,
286
+ kind: 'unsupported',
287
+ stepId,
288
+ summary: resolution.summary,
289
+ actionIds: [],
290
+ };
291
+ blockers.push(blocker);
292
+ steps.push(step({ id: stepId, label: `Capability ${resolution.capabilityId}`, state: 'blocked', dependsOn: ['connectivity'], observation, blocker }));
293
+ continue;
294
+ }
295
+ const action: BootstrapAction = {
296
+ id: `capability.${safeCapabilityId}.${resolution.status === 'installable' ? 'install' : 'repair'}`,
297
+ kind: resolution.status === 'installable' ? 'install' : 'repair',
298
+ owner: 'forge',
299
+ summary: `${resolution.status === 'installable' ? 'Install' : 'Repair'} ${resolution.providerName ?? resolution.providerId} for ${resolution.capabilityId}.`,
300
+ command: `forge plugin install ${resolution.providerId} --controller-home ${JSON.stringify(controllerHome)}`,
301
+ verification: 'forge setup next',
302
+ };
303
+ const blocker = blockerFor(stepId, `BOOTSTRAP_CAPABILITY_${safeCapabilityId.toUpperCase().replaceAll('.', '_').replaceAll('-', '_')}_${resolution.status.toUpperCase()}`, action, resolution.summary);
304
+ actions.push(action); blockers.push(blocker);
305
+ steps.push(step({ id: stepId, label: `Capability ${resolution.capabilityId}`, state: 'blocked', dependsOn: ['connectivity'], observation, blocker, action }));
306
+ }
307
+
308
+ return { desired, observations, steps, blockers, actions };
309
+ }
310
+
311
+ export function createSetupBootstrapControlApi(options: SetupBootstrapOptions = {}): BootstrapControlApi {
312
+ const controllerHome = resolveControllerHome(options.controllerHome);
313
+ const observe = (): BootstrapEvaluation => observeSetupBootstrap({ ...options, controllerHome });
314
+ return createBootstrapControlApi({
315
+ controllerHome,
316
+ now: options.now,
317
+ adapter: {
318
+ observe,
319
+ observeSync: observe,
320
+ perform: async (action) => {
321
+ if (action.id !== 'chatgpt.bridge.bootstrap') throw new Error(`BOOTSTRAP_ACTION_EXECUTOR_UNSUPPORTED: ${action.id}`);
322
+ const platform = options.platform ?? detectSetupPlatform({ env: options.env });
323
+ if (platform.environment !== 'wsl2') throw new Error('CHATGPT_BRIDGE_BOOTSTRAP_WSL_REQUIRED');
324
+ const bridgeRoot = setupBridgeRoot(controllerHome);
325
+ if (!bridgeRoot) throw new Error('CHATGPT_CONTROLLER_BROWSER_ROOT_UNAVAILABLE');
326
+ await bootstrapWslWindowsBridgeBrowser(bridgeRoot, { platform: 'linux', wslDistroName: 'ForgeSetup' });
327
+ },
328
+ },
329
+ });
330
+ }
331
+
332
+ export function refreshSetupBootstrap(options: SetupBootstrapOptions = {}): BootstrapSnapshot {
333
+ return createSetupBootstrapControlApi(options).refreshSync();
334
+ }
@@ -0,0 +1,38 @@
1
+ import { readFileSync, statSync } from 'fs';
2
+ import type { Command } from 'commander';
3
+ import { recordExperience, retractExperience, supersedeExperience, type ExperienceDraft } from '../../../packages/kernel/memory/api/index';
4
+ import { controllerExperienceStore } from '../../runtime/control-plane/persistence/experience-store';
5
+ import { prepareAssistantWorkContext } from '../../runtime/context/assistant-work-context';
6
+
7
+ function readBoundedJson(path: string): unknown {
8
+ if (statSync(path).size > 16 * 1024) throw new Error('BRAIN_INPUT_TOO_LARGE');
9
+ return JSON.parse(readFileSync(path, 'utf8'));
10
+ }
11
+
12
+ /** Thin CLI over the same APIs used by Controller rounds. No independent memory writer. */
13
+ export function addBrainAssistantCommands(brain: Command): void {
14
+ brain.command('recall').description('Resolve registered project knowledge and retained experience for an existing Work')
15
+ .requiredOption('--controller-home <path>').requiredOption('--repo-id <id>').requiredOption('--work-id <id>')
16
+ .option('--query <text>').option('--channel <id>').option('--account <id>').option('--locale <id>')
17
+ .action((options: { controllerHome: string; repoId: string; workId: string; query?: string; channel?: string; account?: string; locale?: string }) => {
18
+ console.log(JSON.stringify(prepareAssistantWorkContext({ ...options, applicability: { channel: options.channel, account: options.account, locale: options.locale } }) ?? { status: 'project_contract_missing' }, null, 2));
19
+ });
20
+ const experience = brain.command('experience').description('Submit or withdraw Controller-authored, evidence-backed experience');
21
+ for (const operation of ['record', 'supersede', 'retract'] as const) {
22
+ experience.command(operation)
23
+ .requiredOption('--controller-home <path>').requiredOption('--repo-id <id>').requiredOption('--work-id <id>')
24
+ .requiredOption('--controller-id <id>').requiredOption('--authority-env <name>', 'Environment variable containing the current Controller capability')
25
+ .requiredOption('--input <path>', 'Bounded JSON API input; never include the Controller capability')
26
+ .action((options: { controllerHome: string; repoId: string; workId: string; controllerId: string; authorityEnv: string; input: string }) => {
27
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(options.authorityEnv)) throw new Error('BRAIN_AUTHORITY_ENV_INVALID');
28
+ const authorityId = process.env[options.authorityEnv];
29
+ if (!authorityId) throw new Error('BRAIN_CONTROLLER_AUTHORITY_REQUIRED');
30
+ const store = controllerExperienceStore({ ...options, identity: { workId: options.workId, controllerId: options.controllerId, authorityId } });
31
+ const data = readBoundedJson(options.input);
32
+ const result = operation === 'record' ? recordExperience(store, data as ExperienceDraft)
33
+ : operation === 'supersede' ? supersedeExperience(store, data as Parameters<typeof supersedeExperience>[1])
34
+ : retractExperience(store, data as Parameters<typeof retractExperience>[1]);
35
+ console.log(JSON.stringify(result, null, 2));
36
+ });
37
+ }
38
+ }