@moretea-labs/forge 1.6.0 → 1.7.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 (396) hide show
  1. package/AGENTS.md +2 -0
  2. package/CHANGELOG.md +26 -0
  3. package/CLAUDE.md +2 -0
  4. package/README.md +2 -2
  5. package/README.zh-CN.md +1 -1
  6. package/SKILL.md +2 -2
  7. package/THIRD_PARTY_NOTICES.md +1 -1
  8. package/agents/openai.yaml +1 -1
  9. package/assets/hooks/hook-input.sh +11 -8
  10. package/assets/hooks/lib/session-state.sh +10 -7
  11. package/assets/hooks/lib/workflow-state.sh +13 -177
  12. package/assets/hooks/post-tool-observer.sh +8 -2
  13. package/assets/hooks/prompt-guard.sh +5 -81
  14. package/assets/hooks/session-start-context.sh +56 -1
  15. package/assets/partials/05-workflow.partial.md +1 -1
  16. package/assets/partials-agents/03-orchestration.partial.md +1 -1
  17. package/assets/plugin-registry.v1.json +1 -1
  18. package/assets/reference-configs/document-generation.md +1 -1
  19. package/assets/reference-configs/harness-overview.md +1 -1
  20. package/assets/reference-configs/sprint-contracts.md +3 -3
  21. package/assets/skill-version.json +2 -2
  22. package/assets/templates/contract.template.md +2 -7
  23. package/assets/templates/helpers/capture-plan.sh +2 -2
  24. package/assets/templates/helpers/check-task-workflow.sh +4 -4
  25. package/assets/templates/helpers/contract-worktree.sh +1 -21
  26. package/assets/templates/helpers/ensure-task-workflow.sh +11 -36
  27. package/assets/templates/helpers/migrate-project-template.sh +22 -45
  28. package/assets/templates/helpers/new-plan.sh +1 -1
  29. package/assets/templates/helpers/plan-to-todo.sh +12 -37
  30. package/assets/templates/helpers/ship-worktrees.sh +2 -29
  31. package/assets/templates/helpers/verify-contract.sh +1 -111
  32. package/assets/templates/helpers/verify-sprint.sh +3 -180
  33. package/assets/templates/plan.template.md +1 -1
  34. package/assets/templates/review.template.md +9 -34
  35. package/assets/workflow-contract.v1.json +10 -19
  36. package/docs/README.md +10 -10
  37. package/docs/architecture/CURRENT.md +170 -0
  38. package/docs/architecture/EVOLUTION.md +42 -0
  39. package/docs/architecture/current/README.md +4 -156
  40. package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +2 -2
  41. package/docs/architecture/decisions/20260823-immediate-controller-relay.md +53 -0
  42. package/docs/architecture/decisions/20260826-browser-runtime-v2.md +73 -0
  43. package/docs/architecture/history/README.md +7 -0
  44. package/docs/architecture/{chatgpt-handoff-facade.md → history/chatgpt-handoff-facade.md} +4 -0
  45. package/docs/architecture/{global-hook-runtime.md → history/global-hook-runtime.md} +7 -3
  46. package/docs/architecture/{ios-semantic-automation-provider-v2.md → history/ios-semantic-automation-provider-v2.md} +6 -2
  47. package/docs/architecture/history.md +3 -34
  48. package/docs/architecture/index.md +15 -98
  49. package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +1 -1
  50. package/docs/architecture/reviews/2026-08-22-semantic-harness-convergence-acceptance.md +39 -0
  51. package/docs/architecture/versions/1.6.md +38 -0
  52. package/docs/architecture/versions/1.7.md +41 -0
  53. package/docs/forge-chatgpt-browser-engine.md +2 -2
  54. package/docs/forge-chatgpt-mcp-setup.md +4 -28
  55. package/docs/forge-chatgpt-supervised-automation.md +3 -3
  56. package/docs/forge-github-issue-launcher.md +1 -1
  57. package/docs/forge-runtime-self-healing-loop.md +1 -1
  58. package/docs/operations/controller-browser-plugin.md +26 -6
  59. package/docs/operations/controller-performance-and-502.md +124 -0
  60. package/docs/operations/controller-reliability-runbook.md +1 -1
  61. package/docs/operations/features.md +2 -2
  62. package/docs/operations/github-repository.md +1 -1
  63. package/docs/operations/homebrew.md +2 -2
  64. package/docs/operations/mcp-tool-exposure.md +5 -3
  65. package/docs/wiki/Architecture.md +6 -6
  66. package/docs/wiki/Implementation.md +2 -2
  67. package/docs/wiki/Integrations.md +2 -2
  68. package/docs/wiki/Work-Lifecycle.md +1 -1
  69. package/package.json +29 -10
  70. package/scripts/activate-source-baseline.ts +17 -13
  71. package/scripts/benchmark-background-check-overlap.ts +228 -0
  72. package/scripts/benchmark-mcp-host.sh +117 -0
  73. package/scripts/benchmark-mcp-transport.ts +170 -0
  74. package/scripts/benchmark-quality-harness.ts +146 -0
  75. package/scripts/benchmark-route-session-concurrency.ts +207 -6
  76. package/scripts/benchmark-thin-harness-mcp-e2e.ts +7 -1
  77. package/scripts/benchmark-typescript-navigation.ts +186 -0
  78. package/scripts/benchmark-work-efficiency.ts +334 -0
  79. package/scripts/capture-plan.sh +3 -3
  80. package/scripts/check-agent-tooling.sh +8 -35
  81. package/scripts/check-architecture-sync.sh +17 -86
  82. package/scripts/check-mcp-compatibility.ts +14 -0
  83. package/scripts/check-runtime-architecture.mjs +107 -64
  84. package/scripts/check-stable-baseline.ts +92 -0
  85. package/scripts/check-task-workflow.sh +4 -4
  86. package/scripts/contract-worktree.sh +1 -21
  87. package/scripts/ensure-task-workflow.sh +22 -55
  88. package/scripts/host-temporary-cloud-mcp-e2e.sh +265 -0
  89. package/scripts/install-standalone-recovery.ts +24 -0
  90. package/scripts/lib/project-init-lib.sh +15 -44
  91. package/scripts/migrate-project-template.sh +23 -1179
  92. package/scripts/new-plan.sh +1 -1
  93. package/scripts/plan-to-todo.sh +11 -36
  94. package/scripts/run-governed-gate.ts +2 -1
  95. package/scripts/ship-worktrees.sh +2 -29
  96. package/scripts/smoke-ios-physical-device.ts +4 -2
  97. package/scripts/smoke-runtime-recovery.ts +1 -35
  98. package/scripts/smoke-schedule-engine.ts +1 -20
  99. package/scripts/verify-contract.sh +1 -111
  100. package/scripts/verify-forge-runtime.sh +0 -1
  101. package/scripts/verify-sprint.sh +3 -180
  102. package/scripts/workflow-contract.ts +1 -5
  103. package/src/cli/commands/init-hook.ts +3 -3
  104. package/src/cli/commands/mcp.ts +9 -5
  105. package/src/cli/commands/plugin.ts +1 -1
  106. package/src/cli/commands/recovery.ts +25 -3
  107. package/src/cli/commands/runtime.ts +55 -3
  108. package/src/cli/commands/security.ts +12 -1
  109. package/src/cli/commands/setup-profile.ts +31 -21
  110. package/src/cli/controller/check-runner.ts +106 -3
  111. package/src/cli/controller/composite-result.ts +1 -1
  112. package/src/cli/controller/context/focus.ts +51 -0
  113. package/src/cli/controller/context/instruction-context.ts +114 -0
  114. package/src/cli/controller/context/known-paths.ts +76 -0
  115. package/src/cli/controller/context/query-planning.ts +110 -0
  116. package/src/cli/controller/context/rule-resolution.ts +532 -0
  117. package/src/cli/controller/context/source-materializer.ts +278 -0
  118. package/src/cli/controller/context/structural.ts +16 -0
  119. package/src/cli/controller/context/types.ts +286 -0
  120. package/src/cli/controller/context-pack.ts +785 -469
  121. package/src/cli/controller/launch-agents.ts +77 -2
  122. package/src/cli/controller/operational-plan.ts +2 -2
  123. package/src/cli/controller/work-mode.ts +6 -4
  124. package/src/cli/editing/edit-session.ts +60 -7
  125. package/src/cli/github/github.ts +133 -0
  126. package/src/cli/installer/managed-entries.ts +15 -1
  127. package/src/cli/local-bridge/console-automations.ts +54 -78
  128. package/src/cli/local-bridge/console-view-models.ts +1 -35
  129. package/src/cli/local-bridge/facade-api.ts +0 -217
  130. package/src/cli/local-bridge/frontend/src/App.tsx +3 -3
  131. package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +23 -13
  132. package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +37 -4
  133. package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +6 -4
  134. package/src/cli/local-bridge/frontend/src/lib/api.ts +1 -6
  135. package/src/cli/local-bridge/frontend/src/lib/routes.ts +1 -1
  136. package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +2 -2
  137. package/src/cli/local-bridge/frontend/src/styles.css +1 -1
  138. package/src/cli/local-bridge/frontend/src/types.ts +5 -8
  139. package/src/cli/local-bridge/job-store.ts +1 -490
  140. package/src/cli/local-bridge/server.ts +0 -513
  141. package/src/cli/local-bridge/ui-dist/app.css +1 -1
  142. package/src/cli/local-bridge/ui-dist/app.js +3703 -3757
  143. package/src/cli/mcp/auth.ts +5 -5
  144. package/src/cli/mcp/instructions.ts +3 -2
  145. package/src/cli/mcp/legacy-tool-service.ts +0 -189
  146. package/src/cli/mcp/multi-repository.ts +16 -5
  147. package/src/cli/mcp/oauth.ts +175 -26
  148. package/src/cli/mcp/repository-tools.ts +247 -107
  149. package/src/cli/mcp/server.ts +537 -111
  150. package/src/cli/mcp/tool-capability-cache.ts +1 -1
  151. package/src/cli/mcp/toolset-selection.ts +1 -1
  152. package/src/cli/mcp/toolset.ts +42 -5
  153. package/src/cli/mcp/transports/http.ts +101 -14
  154. package/src/cli/mcp/transports/session-registry.ts +43 -5
  155. package/src/cli/mcp/types.ts +3 -3
  156. package/src/cli/repositories/command-classifier.ts +101 -19
  157. package/src/cli/repositories/command-executor.ts +55 -521
  158. package/src/cli/repositories/command-process.ts +108 -0
  159. package/src/cli/repositories/command-scope.ts +99 -41
  160. package/src/cli/repositories/controller-home.ts +7 -8
  161. package/src/cli/repositories/git-command-executor.ts +2 -0
  162. package/src/cli/repositories/locks.ts +53 -16
  163. package/src/cli/repositories/repository-snapshot.ts +121 -0
  164. package/src/cli/repositories/selected-path-actions.ts +17 -9
  165. package/src/cli/repositories/structured-git.ts +61 -3
  166. package/src/cli/repository/inspector.ts +553 -63
  167. package/src/cli/repository/session-cache.ts +58 -17
  168. package/src/cli/v81-entry.ts +1 -4
  169. package/src/effects/fs-transaction.ts +85 -17
  170. package/src/runtime/context/codegraph-read-provider.ts +233 -2
  171. package/src/runtime/context/codegraph-sidecar.cjs +74 -40
  172. package/src/runtime/context/generic-lsp-provider.ts +355 -0
  173. package/src/runtime/context/lsp-client.ts +283 -0
  174. package/src/runtime/context/semantic-navigation.ts +275 -0
  175. package/src/runtime/context/swift-navigation.ts +565 -0
  176. package/src/runtime/context/typescript-navigation.ts +226 -0
  177. package/src/runtime/control-plane/dispatch-priority.ts +28 -0
  178. package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +47 -8
  179. package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +86 -24
  180. package/src/runtime/control-plane/execution/session-store.ts +18 -0
  181. package/src/runtime/control-plane/execution/verification-evidence.ts +58 -3
  182. package/src/runtime/control-plane/execution/work-handle-store.ts +27 -2
  183. package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +258 -0
  184. package/src/runtime/control-plane/execution/work-remote-delivery.ts +215 -0
  185. package/src/runtime/control-plane/execution/work-task-receipt.ts +54 -11
  186. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +143 -8
  187. package/src/runtime/control-plane/execution/work-validation-reconciler.ts +22 -14
  188. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +85 -8
  189. package/src/runtime/control-plane/facade/capability-registry.ts +129 -25
  190. package/src/runtime/control-plane/facade/controller-round-relay.ts +991 -0
  191. package/src/runtime/control-plane/facade/controller-session-store.ts +132 -1
  192. package/src/runtime/control-plane/facade/goal-workloop-access.ts +2 -0
  193. package/src/runtime/control-plane/facade/goal-workloop.ts +686 -129
  194. package/src/runtime/control-plane/facade/index.ts +1 -0
  195. package/src/runtime/control-plane/facade/plan-contract-store.ts +185 -20
  196. package/src/runtime/control-plane/facade/semantic-admission.ts +205 -0
  197. package/src/runtime/control-plane/facade/suggested-actions.ts +5 -1
  198. package/src/runtime/control-plane/facade/types.ts +22 -5
  199. package/src/runtime/control-plane/facade/work-contract-store.ts +175 -73
  200. package/src/runtime/control-plane/generated-cache-retention.ts +271 -0
  201. package/src/runtime/control-plane/global-scheduler/config.ts +44 -0
  202. package/src/runtime/control-plane/global-scheduler/dispatch-capacity.ts +80 -0
  203. package/src/runtime/control-plane/global-scheduler/durable-admission.ts +46 -0
  204. package/src/runtime/control-plane/global-scheduler/maintenance.ts +145 -0
  205. package/src/runtime/control-plane/global-scheduler/projection-refresh.ts +84 -0
  206. package/src/runtime/control-plane/global-scheduler/reconciliation.ts +3 -3
  207. package/src/runtime/control-plane/global-scheduler/scheduler.ts +273 -542
  208. package/src/runtime/control-plane/global-scheduler/source-scan.ts +59 -0
  209. package/src/runtime/control-plane/global-scheduler/state.ts +88 -0
  210. package/src/runtime/control-plane/global-scheduler/worker-attachment.ts +57 -0
  211. package/src/runtime/control-plane/global-scheduler/worker-exit-decision.ts +38 -0
  212. package/src/runtime/control-plane/global-scheduler/worker-exit-reconciler.ts +175 -0
  213. package/src/runtime/control-plane/global-scheduler/worker-launch.ts +111 -0
  214. package/src/runtime/control-plane/global-scheduler/worker-lifecycle-store.ts +64 -0
  215. package/src/runtime/control-plane/global-scheduler/worker-lifecycle.ts +150 -0
  216. package/src/runtime/control-plane/global-scheduler/worker-process.ts +119 -0
  217. package/src/runtime/control-plane/global-scheduler/worker-stderr.ts +60 -0
  218. package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +50 -0
  219. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +355 -116
  220. package/src/runtime/control-plane/launcher/launch-reservation-store.ts +40 -0
  221. package/src/runtime/control-plane/launcher/thin-launcher.ts +194 -10
  222. package/src/runtime/control-plane/persistence/controller-home-migration.ts +487 -0
  223. package/src/runtime/control-plane/persistence/sqlite-store.ts +33 -2
  224. package/src/runtime/control-plane/release-retention.ts +62 -2
  225. package/src/runtime/control-plane/routing/route-policy.ts +7 -16
  226. package/src/runtime/control-plane/runtime-status-client.ts +0 -2
  227. package/src/runtime/diagnostics/mcp-timing.ts +13 -0
  228. package/src/runtime/diagnostics/mcp-transport-benchmark.ts +129 -0
  229. package/src/runtime/diagnostics/performance.ts +24 -1
  230. package/src/runtime/evidence/event-ledger.ts +1 -1
  231. package/src/runtime/execution/jobs/store.ts +58 -4
  232. package/src/runtime/execution/jobs/types.ts +1 -1
  233. package/src/runtime/execution/managed-workspace.ts +203 -1
  234. package/src/runtime/execution/process-runtime/check-facade.ts +51 -4
  235. package/src/runtime/execution/process-runtime/check-result.ts +53 -0
  236. package/src/runtime/execution/process-runtime/check-scheduling.ts +114 -0
  237. package/src/runtime/execution/process-runtime/command-facade.ts +345 -40
  238. package/src/runtime/execution/process-runtime/gc.ts +38 -6
  239. package/src/runtime/execution/process-runtime/lightweight-managed.ts +1184 -0
  240. package/src/runtime/execution/process-runtime/persisted-check.ts +47 -4
  241. package/src/runtime/execution/process-runtime/resource-claims.ts +10 -6
  242. package/src/runtime/execution/process-runtime/runtime.ts +43 -3
  243. package/src/runtime/execution/process-runtime/store.ts +1 -0
  244. package/src/runtime/execution/process-runtime/types.ts +2 -0
  245. package/src/runtime/execution/thin-harness/async-process.ts +12 -2
  246. package/src/runtime/execution/thin-harness/search-worker.ts +54 -5
  247. package/src/runtime/execution/workers/executor.ts +0 -48
  248. package/src/runtime/gateway/mcp/execution-tools.ts +1192 -114
  249. package/src/runtime/gateway/mcp/process-tools.ts +83 -37
  250. package/src/runtime/gateway/mcp/router.ts +184 -82
  251. package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +546 -0
  252. package/src/runtime/gateway/mcp/runtime-tools.ts +2224 -1589
  253. package/src/runtime/plugins/app-store-connect-adapter.ts +123 -19
  254. package/src/runtime/plugins/browser-adapter.ts +2901 -241
  255. package/src/runtime/plugins/browser-automation-service.ts +10 -0
  256. package/src/runtime/plugins/browser-handoff.ts +92 -2
  257. package/src/runtime/plugins/browser-macos-bridge.ts +582 -49
  258. package/src/runtime/plugins/browser-node-bridge.ts +6 -34
  259. package/src/runtime/plugins/browser-provider-registry.ts +109 -0
  260. package/src/runtime/plugins/browser-runtime-contract.ts +152 -0
  261. package/src/runtime/plugins/browser-runtime.ts +183 -0
  262. package/src/runtime/plugins/browser-session-authority.ts +332 -0
  263. package/src/runtime/plugins/capability-authorization-grants.ts +354 -0
  264. package/src/runtime/plugins/desktop-operator-registration.ts +8 -2
  265. package/src/runtime/plugins/external-adapter.ts +324 -3
  266. package/src/runtime/plugins/external-unix-socket.ts +7 -1
  267. package/src/runtime/plugins/first-party-registry.ts +2 -0
  268. package/src/runtime/plugins/github-adapter.ts +125 -0
  269. package/src/runtime/plugins/ios/agent-device-provider.ts +1 -1
  270. package/src/runtime/plugins/ios/agent-device-typed-provider.ts +52 -9
  271. package/src/runtime/plugins/ios/remote-xpc-hid.ts +1171 -0
  272. package/src/runtime/plugins/ios-adapter.ts +106 -16
  273. package/src/runtime/plugins/ios-agent-device.ts +234 -64
  274. package/src/runtime/plugins/ios-physical-device.ts +1143 -392
  275. package/src/runtime/plugins/lightweight-action.ts +153 -0
  276. package/src/runtime/plugins/local-system-adapter.ts +123 -6
  277. package/src/runtime/plugins/macos-capability-broker.ts +55 -9
  278. package/src/runtime/plugins/plugin-action-sidecar.ts +59 -0
  279. package/src/runtime/plugins/plugin-management-adapter.ts +49 -8
  280. package/src/runtime/plugins/resend-adapter.ts +1 -1
  281. package/src/runtime/plugins/store.ts +269 -29
  282. package/src/runtime/plugins/types.ts +35 -2
  283. package/src/runtime/plugins/xiaohongshu-publish.ts +515 -0
  284. package/src/runtime/projections/git-status-sampler.ts +16 -16
  285. package/src/runtime/projections/materialized-view.ts +28 -10
  286. package/src/runtime/recovery/maintenance-executor.ts +393 -28
  287. package/src/runtime/root/mcp-transport.ts +180 -10
  288. package/src/runtime/root/package-connector-service.ts +186 -8
  289. package/src/runtime/root/package-runtime-release.ts +143 -17
  290. package/src/runtime/root/package-runtime-service.ts +430 -22
  291. package/src/runtime/root/release-manifest.ts +7 -2
  292. package/src/runtime/root/release-materialize.ts +19 -0
  293. package/src/runtime/root/release-store.ts +48 -11
  294. package/src/runtime/root/runtime.ts +23 -5
  295. package/src/runtime/root/service.ts +100 -29
  296. package/src/runtime/root/types.ts +2 -0
  297. package/src/runtime/safe-tooling/ios-development.ts +321 -63
  298. package/src/runtime/shared/trusted-executable.ts +62 -0
  299. package/src/runtime/shared/trusted-node-executable.ts +48 -0
  300. package/src/runtime/standalone-recovery/core.ts +700 -92
  301. package/src/runtime/standalone-recovery/entry.ts +99 -23
  302. package/src/runtime/standalone-recovery/installer.ts +19 -3
  303. package/src/runtime/standalone-recovery/service-labels.ts +2 -0
  304. package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +160 -0
  305. package/src/runtime/workflow/schedules/browser-probe.ts +81 -3
  306. package/src/runtime/workflow/schedules/engine.ts +287 -151
  307. package/src/runtime/workflow/schedules/github-issue-watch.ts +158 -0
  308. package/src/runtime/workflow/schedules/settlement.ts +48 -4
  309. package/src/runtime/workflow/schedules/store.ts +131 -10
  310. package/src/runtime/workflow/schedules/types.ts +2 -4
  311. package/src/runtime/workflow/schedules/work-continuation.ts +26 -13
  312. package/src/testing/test-governance.ts +8 -40
  313. package/assets/reference-configs/heartbeat-triage.md +0 -57
  314. package/assets/templates/helpers/harness-trace-grade.sh +0 -150
  315. package/assets/templates/helpers/heartbeat-triage.sh +0 -361
  316. package/assets/templates/helpers/maintenance-triage.sh +0 -167
  317. package/docs/architecture/current/approved-target-architecture.zh-CN.md +0 -1501
  318. package/docs/architecture/current/architecture-invariants.md +0 -331
  319. package/docs/architecture/current/automation-and-schedule-engine.md +0 -459
  320. package/docs/architecture/current/codegraph-context-provider.md +0 -238
  321. package/docs/architecture/current/control-plane-authority-inventory.md +0 -94
  322. package/docs/architecture/current/controller-repository-decoupling.md +0 -148
  323. package/docs/architecture/current/dispatch-and-agent-strategy.md +0 -373
  324. package/docs/architecture/current/entity-model.md +0 -612
  325. package/docs/architecture/current/external-plugin-governance.md +0 -396
  326. package/docs/architecture/current/failure-recovery.md +0 -447
  327. package/docs/architecture/current/governance.md +0 -213
  328. package/docs/architecture/current/human-interaction-plane.md +0 -87
  329. package/docs/architecture/current/implementation-status.md +0 -128
  330. package/docs/architecture/current/job-and-run-lifecycle.md +0 -413
  331. package/docs/architecture/current/legacy-governance.md +0 -58
  332. package/docs/architecture/current/local-workspace-target-grants.md +0 -70
  333. package/docs/architecture/current/migration-roadmap.md +0 -105
  334. package/docs/architecture/current/multi-repository-execution.md +0 -371
  335. package/docs/architecture/current/operations-runbook.md +0 -45
  336. package/docs/architecture/current/peer-supercontroller-runtime.md +0 -32
  337. package/docs/architecture/current/personal-assistant-plugin-baseline.md +0 -206
  338. package/docs/architecture/current/repository-access-modes.md +0 -102
  339. package/docs/architecture/current/route-policy.md +0 -15
  340. package/docs/architecture/current/route-session-concurrency.md +0 -85
  341. package/docs/architecture/current/runtime-architecture-simplification.md +0 -214
  342. package/docs/architecture/current/runtime-directory-map.md +0 -49
  343. package/docs/architecture/current/runtime-health-and-resource-lifecycle.md +0 -85
  344. package/docs/architecture/current/scheduler-and-resource-claims.md +0 -422
  345. package/docs/architecture/current/session-aware-execution-and-authorization.md +0 -77
  346. package/docs/architecture/current/system-overview.md +0 -169
  347. package/docs/architecture/current/target-requirements-traceability.md +0 -202
  348. package/docs/architecture/current/thin-harness-governance-policy.md +0 -32
  349. package/docs/architecture/current/thin-harness-v1.md +0 -321
  350. package/docs/architecture/current/verification-and-release-gates.md +0 -391
  351. package/docs/forge-autonomous-goal-loop.md +0 -9
  352. package/docs/forge-provider-configuration.md +0 -7
  353. package/docs/operations/chatgpt-personal-assistant-runtime.md +0 -93
  354. package/docs/operations/gmail-assistant-routines.md +0 -186
  355. package/docs/operations/personal-assistant-operator-guide.md +0 -61
  356. package/docs/operations/provider-configuration.md +0 -31
  357. package/scripts/harness-trace-grade.sh +0 -150
  358. package/scripts/heartbeat-triage.sh +0 -361
  359. package/scripts/maintenance-triage.sh +0 -167
  360. package/src/cli/local-bridge/frontend/src/features/settings/SettingsView.tsx +0 -2
  361. package/src/cli/repositories/goal-registry.ts +0 -239
  362. package/src/runtime/assistant/action-proposals.ts +0 -279
  363. package/src/runtime/assistant/intent.ts +0 -395
  364. package/src/runtime/assistant/model-provider.ts +0 -460
  365. package/src/runtime/assistant/openapi.ts +0 -223
  366. package/src/runtime/assistant/policy.ts +0 -89
  367. package/src/runtime/assistant/readiness.ts +0 -258
  368. package/src/runtime/assistant/routine-runtime.ts +0 -477
  369. package/src/runtime/assistant/schedule-binding.ts +0 -171
  370. package/src/runtime/assistant/standing-grants.ts +0 -375
  371. package/src/runtime/assistant/store.ts +0 -243
  372. package/src/runtime/assistant/types.ts +0 -135
  373. package/src/runtime/control-plane/goal-loop/config-facade.ts +0 -700
  374. package/src/runtime/control-plane/goal-loop/config-store.ts +0 -570
  375. package/src/runtime/control-plane/goal-loop/config-types.ts +0 -213
  376. package/src/runtime/control-plane/goal-loop/executor-router.ts +0 -109
  377. package/src/runtime/control-plane/goal-loop/failure-taxonomy.ts +0 -149
  378. package/src/runtime/control-plane/goal-loop/goal-contract-store.ts +0 -304
  379. package/src/runtime/control-plane/goal-loop/goal-loop-engine.ts +0 -1001
  380. package/src/runtime/control-plane/goal-loop/handoff-packet.ts +0 -160
  381. package/src/runtime/control-plane/goal-loop/index.ts +0 -13
  382. package/src/runtime/control-plane/goal-loop/local-tools.ts +0 -290
  383. package/src/runtime/control-plane/goal-loop/policy-gates.ts +0 -203
  384. package/src/runtime/control-plane/goal-loop/provider-dispatch.ts +0 -93
  385. package/src/runtime/control-plane/goal-loop/provider-registry.ts +0 -545
  386. package/src/runtime/control-plane/goal-loop/types.ts +0 -378
  387. package/src/runtime/control-plane/startup-recovery.ts +0 -198
  388. package/src/runtime/gateway/mcp/resource-policy.ts +0 -186
  389. package/src/runtime/personal-assistant/gmail-triage-manager.ts +0 -231
  390. package/src/runtime/personal-assistant/reporting-runtime.ts +0 -344
  391. package/src/runtime/personal-assistant/triage-runtime.ts +0 -748
  392. package/src/runtime/workflow/findings/store.ts +0 -204
  393. package/src/runtime/workflow/findings/types.ts +0 -58
  394. package/src/runtime/workflow/portfolio/engine.ts +0 -20
  395. package/src/runtime/workflow/portfolio/store.ts +0 -185
  396. package/src/runtime/workflow/portfolio/types.ts +0 -29
@@ -26,8 +26,8 @@ These features are part of the default local setup:
26
26
  | Tailscale / Cloudflare | Stable HTTPS endpoint for ChatGPT MCP | Tunnel client and appropriate account/domain configuration. |
27
27
  | Browser | Playwright navigation, screenshots, and bounded browser evidence | Browser binaries and HTTP(S) URL scheme validation. |
28
28
  | CodeGraph | Additional code relationships and impact navigation | CodeGraph CLI; native Windows automatic setup is not yet enabled. |
29
- | Google Workspace | Gmail and Calendar assistant actions | Explicit OAuth setup and plugin permission. |
30
- | Schedules and findings | Supervised recurring checks and candidate findings | Canonical Forge Runtime running; live actions remain policy-gated. |
29
+ | Google Workspace | Gmail and Calendar plugin actions | Explicit OAuth setup and plugin permission. |
30
+ | Schedules | Supervised recurring checks | Canonical Forge Runtime running; live actions remain policy-gated. |
31
31
 
32
32
  ## Tool exposure
33
33
 
@@ -42,7 +42,7 @@ Use Issues for reproducible defects and scoped feature requests. Use Discussions
42
42
 
43
43
  ## Documentation ownership
44
44
 
45
- The GitHub Wiki is a presentation target. Versioned source lives under `docs/wiki/`. Deeper engineering detail remains under `docs/architecture/current/` and `docs/operations/`.
45
+ The GitHub Wiki is a presentation target. Versioned source lives under `docs/wiki/`. Deeper engineering detail remains under `docs/architecture/CURRENT.md` and `docs/operations/`.
46
46
 
47
47
  Public documentation must distinguish current facts from historical evidence. Avoid hard-coding “next release” versions in operational runbooks; derive versions from `package.json` so routine releases do not leave stale docs behind.
48
48
 
@@ -6,8 +6,8 @@ Homebrew is planned as a convenience layer after the first stable npm/GitHub rel
6
6
 
7
7
  Do not publish a formula until all of the following are true:
8
8
 
9
- - `@moretea-labs/forge@1.6.0` exists on npm;
10
- - Git tag and GitHub Release `v1.6.0` exist and point to the tested commit;
9
+ - `@moretea-labs/forge@1.7.0` exists on npm;
10
+ - Git tag and GitHub Release `v1.7.0` exist and point to the tested commit;
11
11
  - the npm tarball has an immutable checksum;
12
12
  - macOS installation and `forge --version` / `forge doctor` tests pass;
13
13
  - upgrade and uninstall behavior is documented.
@@ -6,8 +6,9 @@ Controller MCP uses one stable default schema so ChatGPT can reliably read, edit
6
6
 
7
7
  | Toolset | CLI | Behavior |
8
8
  | --- | --- | --- |
9
- | **advanced** (default) | `--toolset advanced` | Stable repair-capable surface, capped at 128 tools. Includes the five `rh_*` facades plus high-value repository, Direct Edit, command, Git, Work/Job, Agent, Goal/Work, plugin, browser, iOS, artifact, and recovery tools. |
10
- | **core** | `--toolset core` | Compatibility label for the same stable default schema. It does not reduce capability or require reconnecting. |
9
+ | **facade** (opt-in) | `--toolset facade` | Five-tool ChatGPT orchestration surface: `rh_access`, `rh_status`, `rh_inbox`, `rh_context`, `rh_work`. Internal handlers and capabilities remain registered; only MCP discovery is reduced. Intended for latency/tool-selection A/B before any default migration. |
10
+ | **advanced** (default) | `--toolset advanced` | Current stable 19-tool controller surface. Includes the five `rh_*` facades plus repository, Direct Edit, command, check, plugin-dispatch, Process, and result/evidence tools. |
11
+ | **core** | `--toolset core` | Compatibility label for the same stable default 19-tool schema. It does not reduce capability or require reconnecting. |
11
12
  | **full** | `--toolset full` | Every historical legacy and runtime definition. Use only for old integrations or deep compatibility diagnosis because the much larger schema can reduce tool-selection quality. |
12
13
 
13
14
  Configure via CLI flags, `FORGE_MCP_TOOLSET`, or Controller Home MCP config. Empty/default controller configuration resolves to `advanced`.
@@ -31,7 +32,7 @@ The current implementation separates orchestration from capability without delet
31
32
  2. **Typed atomic tools:** repository inspection, Direct Edit, command, Git, Work/Job, Issue/Task, Goal/Work, plugin, browser, iOS, artifact, and recovery handlers remain public because their schemas preserve operation-specific validation and evidence.
32
33
  3. **Internal handlers and capability registry:** capabilities are grouped as `controller`, `repository-core`, `git`, `issue-task`, `browser`, `ios`, `plugin`, `evidence`, and `runtime-maintenance`. `rh_status`, `rh_context`, and `controller_capabilities` expose this metadata.
33
34
 
34
- The MCP transport currently publishes a static stable schema. It does **not** support loading a domain schema only after ChatGPT selects that domain. Therefore capability grouping improves selection and documentation, but it must not be described as dynamic tool loading. A future transport-level implementation may reduce the discovered schema while retaining the same internal handlers.
35
+ The MCP transport publishes a static schema for each selected toolset. It does **not** dynamically load a domain schema after ChatGPT selects that domain. The opt-in `facade` toolset reduces initial discovery to five facade tools while retaining the same internal handlers; `core`/`advanced` keep the current 19-tool stable schema and `full` keeps the exhaustive compatibility schema.
35
36
 
36
37
  Capability metadata changes do not change `tools/list`; restart the Controller to load new code, but reconnect/rescan ChatGPT only when tool names or input schemas change.
37
38
 
@@ -45,6 +46,7 @@ Remote writes, destructive actions, outside-repository paths, and secret access
45
46
 
46
47
  - Prefer `rh_status`, `rh_access`, `rh_context`, `rh_work`, and `rh_inbox` for normal orchestration.
47
48
  - Use first-class Direct Edit, command, Git, `quick_agent_session`, Goal/Work, iOS, plugin, and artifact tools when the facade is not the shortest reliable path.
49
+ - Use `--toolset facade` only for explicit experiments/clients until latency and workflow coverage are validated; the default remains the stable 19-tool surface.
48
50
  - Keep the stable surface unique and at or below 128 tools.
49
51
  - Add new public tools only when they unlock a real end-to-end workflow; otherwise route capabilities through an existing facade or plugin action.
50
52
 
@@ -75,11 +75,11 @@ One Canonical Runtime owns the active local execution authority and one whole-re
75
75
 
76
76
  ## Authoritative documents
77
77
 
78
- - [System overview](https://github.com/moretea-labs/forge/blob/main/docs/architecture/current/system-overview.md)
79
- - [Architecture invariants](https://github.com/moretea-labs/forge/blob/main/docs/architecture/current/architecture-invariants.md)
80
- - [Multi-repository execution](https://github.com/moretea-labs/forge/blob/main/docs/architecture/current/multi-repository-execution.md)
81
- - [Verification and release gates](https://github.com/moretea-labs/forge/blob/main/docs/architecture/current/verification-and-release-gates.md)
82
- - [Implementation status](https://github.com/moretea-labs/forge/blob/main/docs/architecture/current/implementation-status.md)
83
- - [Runtime directory map](https://github.com/moretea-labs/forge/blob/main/docs/architecture/current/runtime-directory-map.md)
78
+ - [System overview](https://github.com/moretea-labs/forge/blob/main/docs/architecture/../architecture/CURRENT.md)
79
+ - [Architecture invariants](https://github.com/moretea-labs/forge/blob/main/docs/architecture/../architecture/CURRENT.md)
80
+ - [Multi-repository execution](https://github.com/moretea-labs/forge/blob/main/docs/architecture/../architecture/CURRENT.md)
81
+ - [Verification and release gates](https://github.com/moretea-labs/forge/blob/main/docs/architecture/../architecture/CURRENT.md)
82
+ - [Implementation status](https://github.com/moretea-labs/forge/blob/main/docs/architecture/../architecture/CURRENT.md)
83
+ - [Runtime directory map](https://github.com/moretea-labs/forge/blob/main/docs/architecture/../architecture/CURRENT.md)
84
84
 
85
85
  Historical snapshots explain previous designs but are not current Runtime contracts.
@@ -143,8 +143,8 @@ Primary code and docs:
143
143
  ```text
144
144
  src/runtime/root/release-store.ts
145
145
  src/runtime/health/
146
- docs/architecture/current/failure-recovery.md
147
- docs/architecture/current/verification-and-release-gates.md
146
+ docs/architecture/../architecture/CURRENT.md
147
+ docs/architecture/../architecture/CURRENT.md
148
148
  ```
149
149
 
150
150
  The primary Runtime cannot be the only authority deciding its own recovery. Standalone Recovery observes the Runtime independently and may perform bounded whole-release restart/rollback only under its own evidence and lock contract.
@@ -18,9 +18,9 @@ GitHub operations cover issues, pull requests, checks, repository settings, Wiki
18
18
 
19
19
  Browser and local-system plugins are optional controller capabilities. They use separate grants and do not turn repository access into unrestricted machine access.
20
20
 
21
- ## Google Workspace and personal workflows
21
+ ## Google Workspace
22
22
 
23
- Gmail, Calendar, Contacts, and related assistant routines remain connector-specific. Credentials and personal data are not stored in repository source.
23
+ Gmail, Calendar, Contacts, and other Workspace integrations remain connector-specific. Credentials and personal data are not stored in repository source.
24
24
 
25
25
  ## Apple tooling
26
26
 
@@ -28,4 +28,4 @@ Commit explicit paths, merge through the intended strategy, and record the integ
28
28
 
29
29
  Update task evidence, delete merged branches and temporary worktrees, and verify the target branch is clean. Blocked or failed states remain recoverable; they are not treated as immutable terminal truth.
30
30
 
31
- For detailed lifecycle contracts, see [Job and Run Lifecycle](https://github.com/moretea-labs/forge/blob/main/docs/architecture/current/job-and-run-lifecycle.md).
31
+ For detailed lifecycle contracts, see [Job and Run Lifecycle](https://github.com/moretea-labs/forge/blob/main/docs/architecture/../architecture/CURRENT.md).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moretea-labs/forge",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "Local-first action assistant for software work with resumable execution, bounded tools, and reviewable evidence",
5
5
  "license": "MIT",
6
6
  "author": "Moretea Labs contributors",
@@ -54,8 +54,6 @@
54
54
  "docs/forge-chatgpt-mcp-setup.md",
55
55
  "docs/forge-github-issue-launcher.md",
56
56
  "docs/forge-runtime-self-healing-loop.md",
57
- "docs/forge-autonomous-goal-loop.md",
58
- "docs/forge-provider-configuration.md",
59
57
  "docs/forge-plugin-management.md",
60
58
  "README.en.md",
61
59
  "README.zh-CN.md",
@@ -83,7 +81,21 @@
83
81
  "check:controller-ui": "bun scripts/build-controller-ui.ts --check",
84
82
  "check:design": "npx -y @google/design.md@0.4.0 lint DESIGN.md",
85
83
  "benchmark:skills": "bun scripts/run-skill-evals.ts",
84
+ "benchmark:controller-hotpath": "bun scripts/benchmark-controller-hotpath.ts",
85
+ "benchmark:thin-harness-mcp-e2e": "bun scripts/benchmark-thin-harness-mcp-e2e.ts --json",
86
+ "benchmark:mcp-transport": "bun scripts/benchmark-mcp-transport.ts",
87
+ "benchmark:mcp-host": "bash scripts/benchmark-mcp-host.sh",
88
+ "benchmark:work-efficiency": "bun scripts/benchmark-work-efficiency.ts",
86
89
  "benchmark:route-session-concurrency": "bun scripts/benchmark-route-session-concurrency.ts",
90
+ "benchmark:quality-harness": "bun scripts/benchmark-quality-harness.ts",
91
+ "benchmark:background-check-overlap": "bun scripts/benchmark-background-check-overlap.ts",
92
+ "check:quality-harness": "bun scripts/benchmark-quality-harness.ts",
93
+ "check:evaluation-framework": "bun test tests/evaluation-framework.test.ts",
94
+ "check:background-check-overlap": "bun scripts/benchmark-background-check-overlap.ts",
95
+ "check:typescript-navigation": "bun scripts/benchmark-typescript-navigation.ts",
96
+ "check:semantic-navigation-providers": "bun test tests/runtime/semantic-navigation-provider.test.ts",
97
+ "check:check-scheduling": "bun test tests/runtime/check-scheduling.test.ts",
98
+ "check:bootstrap-files": "bun test tests/bootstrap-files.test.ts",
87
99
  "test": "bun scripts/test-governance.ts affected",
88
100
  "test:browser-live": "bun tests/live/browser-native-silent.e2e.ts",
89
101
  "test:core": "bun scripts/test-governance.ts core",
@@ -106,6 +118,7 @@
106
118
  "check:main": "bun scripts/run-governed-gate.ts main",
107
119
  "check:ci": "bun run check:main",
108
120
  "check:release": "bun scripts/run-governed-gate.ts release",
121
+ "check:stable-baseline": "bun scripts/check-stable-baseline.ts",
109
122
  "check:release-surface": "bash scripts/check-public-release-surface.sh",
110
123
  "check:release-readiness": "bash scripts/check-release-readiness.sh",
111
124
  "check:open-source-surface": "bash scripts/check-open-source-tracked-surface.sh",
@@ -125,8 +138,8 @@
125
138
  "check:context-files": "forge run check-context-files",
126
139
  "check:deploy-sql": "forge run check-deploy-sql-order",
127
140
  "check:architecture-sync": "forge run check-architecture-sync",
128
- "check:task-sync": "node bin/forge.mjs run check-task-sync",
129
- "check:task-workflow": "bash scripts/check-task-workflow.sh --strict",
141
+ "check:task-sync": "forge run check-task-sync",
142
+ "check:task-workflow": "forge run check-task-workflow --strict",
130
143
  "runtime:activate-source-baseline": "bun scripts/activate-source-baseline.ts request",
131
144
  "plugin:install-desktop-operator": "bun scripts/install-desktop-operator-registration.ts",
132
145
  "sync:brain-docs": "forge run sync-brain-docs --all",
@@ -143,10 +156,10 @@
143
156
  "devDependencies": {
144
157
  "@colbymchenry/codegraph": "1.0.1",
145
158
  "@types/bun": "latest",
146
- "@types/cors": "^2.8.17",
147
- "@types/express": "^5.0.0",
148
- "@types/react": "^19.2.0",
149
- "@types/react-dom": "^19.2.0",
159
+ "@types/cors": "^2.8.19",
160
+ "@types/express": "^5.0.6",
161
+ "@types/react": "^19.2.18",
162
+ "@types/react-dom": "^19.2.4",
150
163
  "@vitejs/plugin-react": "^5.2.0",
151
164
  "vite": "^7.3.0"
152
165
  },
@@ -156,11 +169,17 @@
156
169
  "express": "^5.2.1",
157
170
  "playwright": "^1.54.1",
158
171
  "react": "^19.2.0",
159
- "react-dom": "^19.2.0",
172
+ "react-dom": "^19.2.8",
160
173
  "typescript": "^6.0.3"
161
174
  },
162
175
  "packageManager": "npm@10.0.0",
163
176
  "optionalDependencies": {
177
+ "@colbymchenry/codegraph-darwin-arm64": "1.0.1",
178
+ "@colbymchenry/codegraph-darwin-x64": "1.0.1",
179
+ "@colbymchenry/codegraph-linux-arm64": "1.0.1",
180
+ "@colbymchenry/codegraph-linux-x64": "1.0.1",
181
+ "@colbymchenry/codegraph-win32-arm64": "1.0.1",
182
+ "@colbymchenry/codegraph-win32-x64": "1.0.1",
164
183
  "agent-device": "0.20.2"
165
184
  }
166
185
  }
@@ -64,19 +64,17 @@ interface CheckDefinition {
64
64
  const CHECKS: readonly CheckDefinition[] = [
65
65
  { id: 'package:check:type', args: ['run', 'check:type'], timeoutMs: 10 * 60_000 },
66
66
  { id: 'package:check:runtime-architecture', args: ['run', 'check:runtime-architecture'], timeoutMs: 3 * 60_000 },
67
- {
68
- id: 'focused:runtime-architecture-replacement',
69
- args: [
70
- 'test',
71
- 'tests/runtime/process-runtime.test.ts',
72
- 'tests/runtime/work-terminal-cleanup.test.ts',
73
- 'tests/runtime/canonical-single-runtime.test.ts',
74
- 'tests/cli/runtime-command.test.ts',
75
- 'tests/runtime/stable-state-and-bootstrap.test.ts',
76
- 'tests/cli/mcp-controller.test.ts',
77
- ],
78
- timeoutMs: 15 * 60_000,
79
- },
67
+ ...[
68
+ 'tests/runtime/process-runtime.test.ts',
69
+ 'tests/runtime/work-terminal-cleanup.test.ts',
70
+ 'tests/runtime/canonical-single-runtime.test.ts',
71
+ 'tests/cli/runtime-command.test.ts',
72
+ 'tests/cli/mcp-http.test.ts',
73
+ ].map((path) => ({
74
+ id: `focused:runtime-architecture-replacement:${path}`,
75
+ args: ['test', '--max-concurrency', '1', `./${path}`],
76
+ timeoutMs: 5 * 60_000,
77
+ })),
80
78
  { id: 'package:test:core', args: ['run', 'test:core'], timeoutMs: 30 * 60_000 },
81
79
  ];
82
80
 
@@ -172,6 +170,12 @@ function terminalOutcome(handle: ReturnType<typeof listWorkHandles>[number]): Wo
172
170
 
173
171
  function cleanupSafety(repoRoot: string, worktreePath: string): { safe: boolean; reason?: string } {
174
172
  if (!existsSync(worktreePath)) return { safe: true };
173
+ const repository = runProcess('git', ['rev-parse', '--is-inside-work-tree'], {
174
+ cwd: worktreePath,
175
+ timeoutMs: 10_000,
176
+ maxOutputBytes: 100_000,
177
+ });
178
+ if (!repository.ok || repository.stdout.trim() !== 'true') return { safe: false, reason: 'WORKTREE_NOT_GIT_REPOSITORY' };
175
179
  const status = git(worktreePath, ['status', '--porcelain']);
176
180
  if (status) return { safe: false, reason: 'WORKTREE_DIRTY' };
177
181
  const head = git(worktreePath, ['rev-parse', 'HEAD']);
@@ -0,0 +1,228 @@
1
+ #!/usr/bin/env bun
2
+
3
+ /**
4
+ * Executable goal-drift guard for the managed-check controller path.
5
+ *
6
+ * It deliberately performs useful rh_context work after run_check returns and
7
+ * before its one final dependency join. A future change that turns this into
8
+ * periodic process_wait polling, re-executes the check, or blocks the initial
9
+ * handle return fails the benchmark rather than only a local Process test.
10
+ */
11
+
12
+ import { execFileSync } from 'child_process';
13
+ import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'fs';
14
+ import { tmpdir } from 'os';
15
+ import { join } from 'path';
16
+ import { performance } from 'perf_hooks';
17
+ import { createMcpToolContext } from '../src/cli/mcp/server';
18
+ import { registerRepository } from '../src/cli/repositories/registry';
19
+ import { callRuntimeTool } from '../src/runtime/gateway/mcp/runtime-tools';
20
+ import { callProcessTool } from '../src/runtime/gateway/mcp/process-tools';
21
+ import { routeDurableMcpCall } from '../src/runtime/gateway/mcp/router';
22
+ import { getProcessRecord } from '../src/runtime/execution/process-runtime/store';
23
+ import {
24
+ clearGitIdentityCacheForTest,
25
+ clearGitSnapshotCacheForTest,
26
+ gitSnapshotPerformanceSnapshot,
27
+ } from '../src/cli/repository/inspector';
28
+
29
+ const CHECK_DURATION_MS = 1_200;
30
+ const MAX_INITIAL_HANDLE_LATENCY_MS = 700;
31
+ const MAX_TERMINAL_OBSERVATION_LATENCY_MS = 1_000;
32
+ const root = mkdtempSync(join(tmpdir(), 'forge-background-check-overlap-'));
33
+ const controllerHome = join(root, 'controller');
34
+ const repoRoot = join(root, 'repo');
35
+
36
+ const behavioralContract = {
37
+ originalUserFacingGoal: 'A long focused check must run in the background while Forge continues useful independent work, then synchronize once at the true dependency boundary.',
38
+ invariants: {
39
+ backgroundCheck: 'long_check_returns_a_managed_handle_promptly',
40
+ noPollingWhileUsefulWorkExists: 'zero_process_wait_calls_before_independent_work_finishes',
41
+ dependencyDrivenJoin: 'one_final_process_wait_after_the_dependency_boundary',
42
+ exactlyOnce: 'one_physical_check_execution',
43
+ resultCorrectness: 'terminal_result_matches_the_returned_process_id',
44
+ noAdditionalOrchestration: 'no_execution_job_created_for_the_fast_check_route',
45
+ sourceRetrievalStaysFocused: 'ordinary_rh_context_search_skips_execution_preflight',
46
+ summaryStaysCheap: 'rh_status_summary_avoids_detail_diagnostics',
47
+ },
48
+ antiGoals: [
49
+ 'periodic_process_wait_polling',
50
+ 'synchronous_wait_before_independent_work',
51
+ 'duplicate_check_execution',
52
+ 'source_retrieval_building_unrequested_check_readiness',
53
+ 'summary_status_triggering_detail_diagnostics',
54
+ ],
55
+ validation: 'Runs a real managed check, performs rh_context work before the sole join, and separately asserts the rh_status summary hot path.',
56
+ };
57
+
58
+ function percentile(values: number[], ratio: number): number {
59
+ const sorted = [...values].sort((left, right) => left - right);
60
+ return Math.round((sorted[Math.min(sorted.length - 1, Math.floor(sorted.length * ratio))] ?? 0) * 100) / 100;
61
+ }
62
+
63
+ try {
64
+ mkdirSync(join(repoRoot, 'src'), { recursive: true });
65
+ mkdirSync(join(repoRoot, '.forge'), { recursive: true });
66
+ execFileSync('git', ['init', '-q', '-b', 'main'], { cwd: repoRoot });
67
+ execFileSync('git', ['config', 'user.email', 'benchmark@example.test'], { cwd: repoRoot });
68
+ execFileSync('git', ['config', 'user.name', 'Forge Benchmark'], { cwd: repoRoot });
69
+ writeFileSync(join(repoRoot, 'src', 'fixture.ts'), 'export const backgroundFixture = true;\n');
70
+ const executionMarker = join(root, 'physical-check-executions.txt');
71
+ writeFileSync(join(repoRoot, '.forge', 'checks.json'), JSON.stringify({
72
+ version: 1,
73
+ checks: {
74
+ background: {
75
+ description: 'Synthetic long check for controller overlap behavior.',
76
+ command: [
77
+ process.execPath,
78
+ '-e',
79
+ [
80
+ `require('fs').appendFileSync(${JSON.stringify(executionMarker)}, '1');`,
81
+ `setTimeout(() => { process.stdout.write('BACKGROUND_CHECK_DONE\\n'); process.exit(0); }, ${CHECK_DURATION_MS});`,
82
+ ].join(' '),
83
+ ],
84
+ timeoutMs: 10_000,
85
+ },
86
+ },
87
+ }, null, 2));
88
+ execFileSync('git', ['add', '.'], { cwd: repoRoot });
89
+ execFileSync('git', ['commit', '-qm', 'fixture'], { cwd: repoRoot });
90
+
91
+ const repository = registerRepository({ path: repoRoot, controllerHome, displayName: 'background-check-overlap' });
92
+ const ctx = createMcpToolContext({ controllerHome, profile: 'controller', repo: repoRoot });
93
+
94
+ const startedAt = performance.now();
95
+ const started = await routeDurableMcpCall(ctx, 'run_check', {
96
+ repo_id: repository.repoId,
97
+ check_id: 'background',
98
+ interactive_wait_ms: 0,
99
+ });
100
+ const initialHandleLatencyMs = performance.now() - startedAt;
101
+ const startPayload = started?.structuredContent as Record<string, unknown> | undefined;
102
+ const processId = typeof startPayload?.processId === 'string' ? startPayload.processId : '';
103
+
104
+ const independentStartedAt = performance.now();
105
+ const independent = await callRuntimeTool(ctx, 'rh_context', {
106
+ repo_id: repository.repoId,
107
+ operation: 'search',
108
+ query: 'backgroundFixture',
109
+ known_paths: ['src/fixture.ts'],
110
+ structural_context: 'off',
111
+ });
112
+ const independentOperationLatencyMs = performance.now() - independentStartedAt;
113
+ const independentPayload = independent?.structuredContent as { data?: Record<string, unknown> } | undefined;
114
+ const independentData = independentPayload?.data;
115
+ const independentRetrievalPolicy = independentData?.retrievalPolicy as Record<string, unknown> | undefined;
116
+ const sourceRetrievalSkippedExecutionPreflight = independentData?.executionReadiness === undefined
117
+ && independentData?.registeredChecks === undefined
118
+ && independentRetrievalPolicy?.executionReadiness === 'requested_check_ids_only';
119
+ const processWaitCallsBeforeDependencyBoundary = 0;
120
+
121
+ const joinStartedAtMs = Date.now();
122
+ const joined = processId
123
+ ? await callProcessTool(ctx, 'process_wait', {
124
+ repo_id: repository.repoId,
125
+ process_id: processId,
126
+ timeout_ms: 10_000,
127
+ })
128
+ : undefined;
129
+ const resultObservedAtMs = Date.now();
130
+ const finalSynchronizationCount = processId ? 1 : 0;
131
+ const joinedPayload = joined?.structuredContent as { process?: { processId?: string; completed?: boolean; ok?: boolean } } | undefined;
132
+ const record = processId ? getProcessRecord(controllerHome, repository.repoId, processId) : undefined;
133
+ const finishedAtMs = record?.finishedAt ? Date.parse(record.finishedAt) : NaN;
134
+ const completionToObservationLatencyMs = Number.isFinite(finishedAtMs)
135
+ ? Math.max(0, resultObservedAtMs - finishedAtMs)
136
+ : undefined;
137
+ const physicalExecutionCount = readFileSync(executionMarker, 'utf8').length;
138
+
139
+ // Summary is a separate hot path: it must answer readiness without falling
140
+ // into the full Git status/diff-stat or maintenance/detail projection.
141
+ clearGitIdentityCacheForTest();
142
+ clearGitSnapshotCacheForTest();
143
+ const statusSummaryDurations: number[] = [];
144
+ let summaryPayload: Record<string, unknown> | undefined;
145
+ for (let iteration = 0; iteration < 7; iteration += 1) {
146
+ const statusStartedAt = performance.now();
147
+ const status = await callRuntimeTool(ctx, 'rh_status', { repo_id: repository.repoId, detail_level: 'summary' });
148
+ statusSummaryDurations.push(performance.now() - statusStartedAt);
149
+ summaryPayload = status?.structuredContent as Record<string, unknown> | undefined;
150
+ }
151
+ // Snapshot this before the intentional detail call below: detail is allowed
152
+ // to build the full Git projection, while summary is not.
153
+ const summaryGitSnapshot = gitSnapshotPerformanceSnapshot();
154
+ const detailStartedAt = performance.now();
155
+ const detail = await callRuntimeTool(ctx, 'rh_status', { repo_id: repository.repoId, detail_level: 'detail' });
156
+ const detailElapsedMs = performance.now() - detailStartedAt;
157
+ const detailPayload = detail?.structuredContent as Record<string, unknown> | undefined;
158
+ const detailMeta = detailPayload?.responseMeta as Record<string, unknown> | undefined;
159
+ const summaryData = summaryPayload?.data as Record<string, unknown> | undefined;
160
+ const summaryRepositoryState = summaryData?.repositoryState as Record<string, unknown> | undefined;
161
+ const summaryUsesCompactPayload = Boolean(summaryData)
162
+ && summaryData?.access === undefined
163
+ && summaryData?.pendingHandoffCount === undefined
164
+ && summaryData?.activeWorkCount === undefined
165
+ && summaryData?.activeProcessCount === undefined
166
+ && summaryRepositoryState?.status === undefined
167
+ && summaryRepositoryState?.diffStat === undefined;
168
+
169
+ const assertions = {
170
+ initialManagedHandle: Boolean(processId) && startPayload?.path === 'process_managed' && initialHandleLatencyMs <= MAX_INITIAL_HANDLE_LATENCY_MS,
171
+ independentUsefulOperation: independent?.isError !== true,
172
+ sourceRetrievalSkipsExecutionPreflight: sourceRetrievalSkippedExecutionPreflight,
173
+ noPollingBeforeDependencyBoundary: processWaitCallsBeforeDependencyBoundary === 0,
174
+ oneDependencyJoin: finalSynchronizationCount === 1,
175
+ exactlyOnce: physicalExecutionCount === 1,
176
+ terminalResultCorrect: joinedPayload?.process?.processId === processId && joinedPayload?.process?.completed === true && joinedPayload?.process?.ok === true,
177
+ promptResultObservation: completionToObservationLatencyMs === undefined || completionToObservationLatencyMs <= MAX_TERMINAL_OBSERVATION_LATENCY_MS,
178
+ statusSummaryUsesCompactProjection: Boolean(summaryPayload?.data)
179
+ && summaryGitSnapshot.refreshes === 0
180
+ && summaryGitSnapshot.subprocesses === 0
181
+ && summaryUsesCompactPayload,
182
+ };
183
+ const output = {
184
+ schemaVersion: 1,
185
+ behavioralContract,
186
+ check: {
187
+ configuredDurationMs: CHECK_DURATION_MS,
188
+ initialManagedHandleLatencyMs: Number(initialHandleLatencyMs.toFixed(2)),
189
+ processWaitCallsBeforeDependencyBoundary,
190
+ independentOperation: {
191
+ tool: 'rh_context.search',
192
+ latencyMs: Number(independentOperationLatencyMs.toFixed(2)),
193
+ completed: independent?.isError !== true,
194
+ executionPreflight: sourceRetrievalSkippedExecutionPreflight ? 'not_requested' : 'unexpected',
195
+ },
196
+ finalSynchronizationCount,
197
+ finalJoinDurationMs: resultObservedAtMs - joinStartedAtMs,
198
+ physicalExecutionCount,
199
+ terminalCompletionToObservationLatencyMs: completionToObservationLatencyMs,
200
+ processId,
201
+ },
202
+ status: {
203
+ summaryP50Ms: percentile(statusSummaryDurations, 0.5),
204
+ summaryP95Ms: percentile(statusSummaryDurations, 0.95),
205
+ detailElapsedMs: Number(detailElapsedMs.toFixed(2)),
206
+ detailServerDurationMs: detailMeta?.serverDurationMs,
207
+ detailPhaseTimingsMs: detailMeta?.phaseTimingsMs,
208
+ fullGitSnapshot: summaryGitSnapshot,
209
+ summaryOmissions: {
210
+ maintenance: true,
211
+ plugins: true,
212
+ workState: true,
213
+ accessPolicy: true,
214
+ gitStatusAndDiffStat: true,
215
+ },
216
+ },
217
+ thresholds: {
218
+ initialManagedHandleLatencyMs: MAX_INITIAL_HANDLE_LATENCY_MS,
219
+ terminalCompletionToObservationLatencyMs: MAX_TERMINAL_OBSERVATION_LATENCY_MS,
220
+ },
221
+ assertions,
222
+ passed: Object.values(assertions).every(Boolean),
223
+ };
224
+ process.stdout.write(`${JSON.stringify(output, null, 2)}\n`);
225
+ if (!output.passed) process.exitCode = 1;
226
+ } finally {
227
+ rmSync(root, { recursive: true, force: true });
228
+ }
@@ -0,0 +1,117 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+ BUN_BIN="${BUN_BIN:-bun}"
6
+ LABEL="${FORGE_MCP_BENCH_LABEL:-host-runtime-direct}"
7
+ PORT="${FORGE_MCP_BENCH_PORT:-18765}"
8
+ ITERATIONS="${FORGE_MCP_BENCH_ITERATIONS:-50}"
9
+ CONNECT_ITERATIONS="${FORGE_MCP_BENCH_CONNECT_ITERATIONS:-30}"
10
+
11
+ for value in "$PORT" "$ITERATIONS" "$CONNECT_ITERATIONS"; do
12
+ if ! [[ "$value" =~ ^[0-9]+$ ]] || [[ "$value" == "0" ]]; then
13
+ echo "benchmark:mcp-host requires positive integer port/iteration values" >&2
14
+ exit 2
15
+ fi
16
+ done
17
+ if (( PORT < 1024 || PORT > 65535 )); then
18
+ echo "FORGE_MCP_BENCH_PORT must be between 1024 and 65535" >&2
19
+ exit 2
20
+ fi
21
+
22
+ TMP_ROOT="$(mktemp -d "${TMPDIR:-/tmp}/forge-mcp-host-bench.XXXXXX")"
23
+ CONTROLLER_HOME="$TMP_ROOT/controller-home"
24
+ REGISTER_JSON="$TMP_ROOT/repository.json"
25
+ INSTALL_JSON="$TMP_ROOT/runtime-install.json"
26
+ READY_JSON="$TMP_ROOT/runtime-ready.json"
27
+ STEADY_JSON="$TMP_ROOT/steady.json"
28
+ CONNECT_JSON="$TMP_ROOT/connect.json"
29
+ RUNTIME_PID=""
30
+
31
+ cleanup() {
32
+ if [[ -n "$RUNTIME_PID" ]] && kill -0 "$RUNTIME_PID" 2>/dev/null; then
33
+ kill "$RUNTIME_PID" 2>/dev/null || true
34
+ for _ in $(seq 1 20); do
35
+ kill -0 "$RUNTIME_PID" 2>/dev/null || break
36
+ sleep 0.1
37
+ done
38
+ kill -9 "$RUNTIME_PID" 2>/dev/null || true
39
+ fi
40
+ for _ in $(seq 1 5); do
41
+ rm -rf "$TMP_ROOT" 2>/dev/null && return 0
42
+ sleep 0.1
43
+ done
44
+ rm -rf "$TMP_ROOT" 2>/dev/null || true
45
+ }
46
+ trap cleanup EXIT INT TERM
47
+
48
+ TOKEN="$(node -e "process.stdout.write(require('crypto').randomBytes(32).toString('hex'))")"
49
+ export FORGE_MCP_TOKEN="$TOKEN"
50
+ export FORGE_MCP_BENCH_TOKEN="$TOKEN"
51
+
52
+ cd "$ROOT"
53
+ "$BUN_BIN" bin/forge.mjs repo register "$ROOT" \
54
+ --controller-home "$CONTROLLER_HOME" \
55
+ --json > "$REGISTER_JSON"
56
+ REPO_ID="$(node -e "const x=require(process.argv[1]); const id=x?.repository?.repoId; if(!id) process.exit(2); process.stdout.write(id)" "$REGISTER_JSON")"
57
+
58
+ "$BUN_BIN" bin/forge.mjs runtime service install-package \
59
+ --controller-home "$CONTROLLER_HOME" \
60
+ --host 127.0.0.1 \
61
+ --port "$PORT" \
62
+ --portable > "$INSTALL_JSON"
63
+ RUNTIME_PID="$(node -e "const x=require(process.argv[1]); const pid=x?.pid; if(!Number.isInteger(pid)||pid<=0) process.exit(2); process.stdout.write(String(pid))" "$INSTALL_JSON")"
64
+
65
+ curl --fail --silent --show-error \
66
+ --retry 30 --retry-delay 1 --retry-connrefused \
67
+ "http://127.0.0.1:${PORT}/ready" > "$READY_JSON"
68
+
69
+ "$BUN_BIN" run benchmark:mcp-transport -- \
70
+ --endpoint "http://127.0.0.1:${PORT}/mcp" \
71
+ --label "$LABEL" \
72
+ --repo-id "$REPO_ID" \
73
+ --tool rh_status \
74
+ --iterations "$ITERATIONS" \
75
+ --warmup 3 \
76
+ --timing-log "$CONTROLLER_HOME/audit/mcp-timings.jsonl" > "$STEADY_JSON"
77
+
78
+ "$BUN_BIN" run benchmark:mcp-transport -- \
79
+ --endpoint "http://127.0.0.1:${PORT}/mcp" \
80
+ --label "$LABEL" \
81
+ --repo-id "$REPO_ID" \
82
+ --tool rh_status \
83
+ --iterations "$CONNECT_ITERATIONS" \
84
+ --warmup 0 \
85
+ --include-connect \
86
+ --timing-log "$CONTROLLER_HOME/audit/mcp-timings.jsonl" > "$CONNECT_JSON"
87
+
88
+ node - "$STEADY_JSON" "$CONNECT_JSON" "$READY_JSON" <<'NODE'
89
+ const fs = require('fs');
90
+ const os = require('os');
91
+ const path = require('path');
92
+ const [steadyPath, connectPath, readyPath] = process.argv.slice(2);
93
+ const steady = JSON.parse(fs.readFileSync(steadyPath, 'utf8'));
94
+ const connect = JSON.parse(fs.readFileSync(connectPath, 'utf8'));
95
+ const ready = JSON.parse(fs.readFileSync(readyPath, 'utf8'));
96
+ const report = {
97
+ schemaVersion: 1,
98
+ generatedAt: new Date().toISOString(),
99
+ host: {
100
+ platform: process.platform,
101
+ arch: process.arch,
102
+ cpuCount: os.cpus().length,
103
+ totalMemoryBytes: os.totalmem(),
104
+ },
105
+ ready,
106
+ steady,
107
+ connectInclusive: connect,
108
+ };
109
+ const text = `${JSON.stringify(report, null, 2)}\n`;
110
+ const output = process.env.FORGE_MCP_BENCH_OUTPUT?.trim();
111
+ if (output) {
112
+ const target = path.resolve(output);
113
+ fs.mkdirSync(path.dirname(target), { recursive: true });
114
+ fs.writeFileSync(target, text, 'utf8');
115
+ }
116
+ process.stdout.write(text);
117
+ NODE