@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
@@ -0,0 +1,186 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { execFileSync } from 'child_process';
4
+ import { readFileSync } from 'fs';
5
+ import { resolve } from 'path';
6
+ import { performance } from 'perf_hooks';
7
+ import {
8
+ clearTypeScriptNavigationCache,
9
+ navigateTypeScriptSymbol,
10
+ type TypeScriptNavigationKind,
11
+ } from '../src/runtime/context/typescript-navigation';
12
+
13
+ interface BenchmarkCase {
14
+ label: string;
15
+ path: string;
16
+ symbol: string;
17
+ marker: string;
18
+ }
19
+
20
+ const repoRoot = execFileSync('git', ['rev-parse', '--show-toplevel'], { encoding: 'utf8' }).trim();
21
+ const cases: BenchmarkCase[] = [
22
+ {
23
+ label: 'repository command execution',
24
+ path: 'src/cli/repositories/command-executor.ts',
25
+ symbol: 'executeRepositoryCommand',
26
+ marker: 'export function executeRepositoryCommand(',
27
+ },
28
+ {
29
+ label: 'MCP repository dispatch',
30
+ path: 'src/cli/mcp/repository-tools.ts',
31
+ symbol: 'callRepositoryTool',
32
+ marker: 'export async function callRepositoryTool(',
33
+ },
34
+ {
35
+ label: 'canonical Runtime proxy',
36
+ path: 'src/cli/mcp/server.ts',
37
+ symbol: 'createCanonicalRuntimeProxy',
38
+ marker: 'export function createCanonicalRuntimeProxy(',
39
+ },
40
+ {
41
+ label: 'Runtime MCP dispatch',
42
+ path: 'src/runtime/gateway/mcp/runtime-tools.ts',
43
+ symbol: 'callRuntimeTool',
44
+ marker: 'export async function callRuntimeTool(',
45
+ },
46
+ {
47
+ label: 'Lightweight command execution',
48
+ path: 'src/runtime/execution/process-runtime/lightweight-managed.ts',
49
+ symbol: 'startLightweightRepositoryCommand',
50
+ marker: 'export async function startLightweightRepositoryCommand(',
51
+ },
52
+ ];
53
+ const requestedSymbols = new Set(
54
+ String(process.env.FORGE_TSNAV_BENCHMARK_SYMBOLS ?? '')
55
+ .split(',')
56
+ .map((value) => value.trim())
57
+ .filter(Boolean),
58
+ );
59
+ const benchmarkCases = requestedSymbols.size === 0
60
+ ? cases
61
+ : cases.filter((case_) => requestedSymbols.has(case_.symbol));
62
+ if (benchmarkCases.length === 0) {
63
+ throw new Error(`No benchmark cases match FORGE_TSNAV_BENCHMARK_SYMBOLS=${[...requestedSymbols].join(',')}`);
64
+ }
65
+
66
+ function target(case_: BenchmarkCase): { line: number; column: number } {
67
+ const text = readFileSync(resolve(repoRoot, case_.path), 'utf8');
68
+ const markerOffset = text.indexOf(case_.marker);
69
+ if (markerOffset < 0) throw new Error(`marker not found for ${case_.label}: ${case_.marker}`);
70
+ const symbolOffset = markerOffset + case_.marker.indexOf(case_.symbol);
71
+ const before = text.slice(0, symbolOffset);
72
+ const lines = before.split('\n');
73
+ return { line: lines.length, column: (lines.at(-1)?.length ?? 0) + 1 };
74
+ }
75
+
76
+ function navigate(case_: BenchmarkCase, navigation: TypeScriptNavigationKind) {
77
+ const point = target(case_);
78
+ return navigateTypeScriptSymbol(repoRoot, { navigation, path: case_.path, ...point });
79
+ }
80
+
81
+ function lexicalMatches(symbol: string): string[] {
82
+ try {
83
+ const output = execFileSync('git', ['grep', '-n', '-w', symbol, '--', 'src', 'scripts', 'tests'], {
84
+ cwd: repoRoot,
85
+ encoding: 'utf8',
86
+ maxBuffer: 8 * 1024 * 1024,
87
+ }).trim();
88
+ return output ? output.split('\n') : [];
89
+ } catch {
90
+ return [];
91
+ }
92
+ }
93
+
94
+ function percentile(values: number[], ratio: number): number {
95
+ if (values.length === 0) return 0;
96
+ const sorted = [...values].sort((left, right) => left - right);
97
+ const index = Math.min(sorted.length - 1, Math.floor(sorted.length * ratio));
98
+ return Math.round((sorted[index] ?? 0) * 100) / 100;
99
+ }
100
+
101
+ const results = [];
102
+ for (const case_ of benchmarkCases) {
103
+ clearTypeScriptNavigationCache();
104
+ // This first reference call represents the user-visible cold path.
105
+ const coldReferenceStartedAt = performance.now();
106
+ const coldReferences = navigate(case_, 'references');
107
+ const coldReferenceMs = performance.now() - coldReferenceStartedAt;
108
+
109
+ // Then separately initialize a fresh project through the cheap definition
110
+ // query and measure references on that already-built Language Service. This
111
+ // makes project construction and high-fanout reference cost visible instead
112
+ // of attributing both to one opaque cold number.
113
+ clearTypeScriptNavigationCache();
114
+ const projectSetupStartedAt = performance.now();
115
+ const coldDefinition = navigate(case_, 'definition');
116
+ const projectSetupMs = performance.now() - projectSetupStartedAt;
117
+ const firstReferenceStartedAt = performance.now();
118
+ const firstReferencesOnPreparedProject = navigate(case_, 'references');
119
+ const firstReferenceOnPreparedProjectMs = performance.now() - firstReferenceStartedAt;
120
+
121
+ const warmDurations: number[] = [];
122
+ let warmReferences = firstReferencesOnPreparedProject;
123
+ for (let index = 0; index < 3; index += 1) {
124
+ const startedAt = performance.now();
125
+ warmReferences = navigate(case_, 'references');
126
+ warmDurations.push(performance.now() - startedAt);
127
+ }
128
+ const definitions = navigate(case_, 'definition');
129
+ const implementations = navigate(case_, 'implementations');
130
+ const lexical = lexicalMatches(case_.symbol);
131
+
132
+ results.push({
133
+ label: case_.label,
134
+ symbol: case_.symbol,
135
+ target: { path: case_.path, ...target(case_) },
136
+ semantic: {
137
+ coldReferenceLocations: coldReferences.locations.length,
138
+ coldDefinitionLocations: coldDefinition.locations.length,
139
+ references: warmReferences.locations.length,
140
+ definitions: definitions.locations.length,
141
+ implementations: implementations.locations.length,
142
+ crossFileReferences: warmReferences.locations.filter((location) => location.path !== case_.path).length,
143
+ sampleReferences: warmReferences.locations.slice(0, 8),
144
+ },
145
+ lexical: {
146
+ exactMatches: lexical.length,
147
+ sampleMatches: lexical.slice(0, 8),
148
+ },
149
+ latencyMs: {
150
+ coldReferences: Math.round(coldReferenceMs * 100) / 100,
151
+ projectSetupViaDefinition: Math.round(projectSetupMs * 100) / 100,
152
+ firstReferencesOnPreparedProject: Math.round(firstReferenceOnPreparedProjectMs * 100) / 100,
153
+ warmReferences: warmDurations.map((value) => Math.round(value * 100) / 100),
154
+ },
155
+ });
156
+ }
157
+ clearTypeScriptNavigationCache();
158
+
159
+ const preparedReferenceDurations = results.map((entry) => entry.latencyMs.firstReferencesOnPreparedProject);
160
+ const warmReferenceDurations = results.flatMap((entry) => entry.latencyMs.warmReferences);
161
+ const thresholds = {
162
+ firstReferencesOnPreparedProjectP95MaxMs: 250,
163
+ warmReferencesP95MaxMs: 150,
164
+ };
165
+ const assertions = {
166
+ allDefinitionsResolved: results.every((entry) => entry.semantic.definitions >= 1),
167
+ allReferencesResolved: results.every((entry) => entry.semantic.references >= 1),
168
+ allImplementationsResolved: results.every((entry) => entry.semantic.implementations >= 1),
169
+ crossFileSemanticReferencesResolved: results.every((entry) => entry.semantic.crossFileReferences >= 1),
170
+ preparedReferenceLatencyBounded: percentile(preparedReferenceDurations, 0.95) <= thresholds.firstReferencesOnPreparedProjectP95MaxMs,
171
+ warmReferenceLatencyBounded: percentile(warmReferenceDurations, 0.95) <= thresholds.warmReferencesP95MaxMs,
172
+ };
173
+ const output = {
174
+ repoRoot,
175
+ requestedSymbols: [...requestedSymbols],
176
+ cases: results,
177
+ summary: {
178
+ firstReferencesOnPreparedProjectP95Ms: percentile(preparedReferenceDurations, 0.95),
179
+ warmReferencesP95Ms: percentile(warmReferenceDurations, 0.95),
180
+ },
181
+ thresholds,
182
+ assertions,
183
+ passed: Object.values(assertions).every(Boolean),
184
+ };
185
+ console.log(JSON.stringify(output, null, 2));
186
+ if (!output.passed) process.exitCode = 1;
@@ -0,0 +1,334 @@
1
+ #!/usr/bin/env bun
2
+
3
+ /**
4
+ * Forge Work efficiency benchmark.
5
+ *
6
+ * Measures end-to-end controller ceremony for a tiny, real repository change
7
+ * against isolated temporary repository/controller state. It compares the
8
+ * streamlined path (verify -> finalize) with the legacy-style ceremony
9
+ * (verify -> continue -> finalize) without mutating the Forge checkout.
10
+ */
11
+ import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'fs';
12
+ import { tmpdir } from 'os';
13
+ import { join } from 'path';
14
+ import { spawnSync } from 'child_process';
15
+ import { createMcpToolContext } from '../src/cli/mcp/server';
16
+ import type { MultiRepositoryMcpToolContext } from '../src/cli/mcp/multi-repository';
17
+ import { ensureControllerHome } from '../src/cli/repositories/controller-home';
18
+ import { registerRepository } from '../src/cli/repositories/registry';
19
+ import { callRuntimeTool } from '../src/runtime/gateway/mcp/runtime-tools';
20
+ import { getWorkContract } from '../src/runtime/control-plane/facade/work-contract-store';
21
+ import { waitForProcess } from '../src/runtime/execution/process-runtime';
22
+ import { acquireRuntimeOwnership } from '../src/runtime/root/ownership';
23
+ import { forgeRuntimeServicePaths } from '../src/runtime/root/service';
24
+ import { writeRuntimeStatusSnapshot } from '../src/runtime/root/status';
25
+ import { ensureActiveRuntimeRelease } from '../src/runtime/root/release-store';
26
+ import { bindRuntimeWriteClaim, clearRuntimeWriteClaimForTests } from '../src/runtime/root/write-fence';
27
+
28
+ interface TimedCall {
29
+ elapsedMs: number;
30
+ value: Record<string, any>;
31
+ }
32
+
33
+ interface FlowSample {
34
+ mode: 'streamlined' | 'legacy_ceremony';
35
+ sample: number;
36
+ ok: boolean;
37
+ controllerCalls: number;
38
+ processWaits: number;
39
+ startMs: number;
40
+ verifySubmitMs: number;
41
+ verifyWaitMs: number;
42
+ verifyReattachMs: number;
43
+ continueMs: number;
44
+ finalizeMs: number;
45
+ totalMs: number;
46
+ verificationNextStep?: string;
47
+ finalStatus?: string;
48
+ cleanupComplete: boolean;
49
+ }
50
+
51
+ function argNumber(name: string, fallback: number): number {
52
+ const index = process.argv.indexOf(name);
53
+ if (index < 0) return fallback;
54
+ const parsed = Number(process.argv[index + 1]);
55
+ return Number.isFinite(parsed) && parsed > 0 ? Math.floor(parsed) : fallback;
56
+ }
57
+
58
+ function git(root: string, args: string[]): string {
59
+ const result = spawnSync('git', ['-C', root, ...args], { encoding: 'utf8' });
60
+ if (result.status !== 0) throw new Error(String(result.stderr || `git ${args.join(' ')} failed`));
61
+ return String(result.stdout ?? '').trim();
62
+ }
63
+
64
+ function runtimeManifest(controllerHome: string): string {
65
+ const path = join(controllerHome, 'benchmark-runtime.manifest.json');
66
+ writeFileSync(path, JSON.stringify({
67
+ schemaVersion: 1,
68
+ releaseId: 'release-work-efficiency-benchmark',
69
+ artifactIdentity: 'artifact-work-efficiency-benchmark',
70
+ entrypoint: 'forge-runtime',
71
+ arguments: [],
72
+ configurationSchemaVersion: 1,
73
+ controllerHome,
74
+ databaseSchemaCompatibility: { minimum: 1, maximum: 1 },
75
+ workerProtocolVersion: 1,
76
+ createdAt: new Date().toISOString(),
77
+ }));
78
+ return path;
79
+ }
80
+
81
+ function createFixture(label: string) {
82
+ const root = mkdtempSync(join(tmpdir(), `forge-work-efficiency-${label}-`));
83
+ const controllerHome = join(root, 'controller');
84
+ const repoRoot = join(root, 'repo');
85
+ ensureControllerHome(controllerHome);
86
+ mkdirSync(repoRoot, { recursive: true });
87
+ git(repoRoot, ['init', '-b', 'main']);
88
+ git(repoRoot, ['config', 'user.name', 'Work Efficiency Benchmark']);
89
+ git(repoRoot, ['config', 'user.email', 'benchmark@example.test']);
90
+ writeFileSync(join(repoRoot, 'README.md'), 'fixture\n');
91
+ writeFileSync(join(repoRoot, 'package.json'), JSON.stringify({
92
+ name: `work-efficiency-${label}`,
93
+ private: true,
94
+ scripts: { 'check:bench': 'node -e "process.exit(0)"' },
95
+ }, null, 2));
96
+ git(repoRoot, ['add', '.']);
97
+ git(repoRoot, ['commit', '-m', 'fixture']);
98
+
99
+ const repository = registerRepository({ path: repoRoot, controllerHome, displayName: `work-efficiency-${label}` });
100
+ const owner = acquireRuntimeOwnership(controllerHome, `runtime-work-efficiency-${label}`);
101
+ const authority = ensureActiveRuntimeRelease(controllerHome, runtimeManifest(controllerHome));
102
+ bindRuntimeWriteClaim({ controllerHome, owner: owner.record, authority });
103
+
104
+ const runtimeService = forgeRuntimeServicePaths(controllerHome);
105
+ mkdirSync(runtimeService.serviceRoot, { recursive: true });
106
+ mkdirSync(join(controllerHome, 'mcp'), { recursive: true });
107
+ const runtimeTokenPath = join(controllerHome, 'mcp', 'runtime-token');
108
+ writeFileSync(runtimeTokenPath, `fixture-token-${label}\n`, { mode: 0o600 });
109
+ writeFileSync(runtimeService.configPath, JSON.stringify({
110
+ schemaVersion: 1,
111
+ controllerHome,
112
+ repositoryRoot: repoRoot,
113
+ host: '127.0.0.1',
114
+ port: 9876,
115
+ authTokenFile: runtimeTokenPath,
116
+ }));
117
+ const observedAt = new Date().toISOString();
118
+ writeRuntimeStatusSnapshot(controllerHome, {
119
+ schemaVersion: 1,
120
+ runtimeInstanceId: owner.record.runtimeInstanceId,
121
+ pid: owner.record.pid,
122
+ releaseId: authority.active.releaseId,
123
+ artifactIdentity: authority.active.artifactIdentity,
124
+ endpoint: 'http://127.0.0.1:9876/mcp',
125
+ readiness: {
126
+ ready: true,
127
+ reasonCodes: [],
128
+ diagnostics: {
129
+ database: { outcome: 'pass' },
130
+ scheduler: { outcome: 'pass' },
131
+ releaseCoherence: { outcome: 'pass' },
132
+ mcpEndToEnd: { outcome: 'pass' },
133
+ },
134
+ observedAt,
135
+ },
136
+ startedAt: observedAt,
137
+ updatedAt: observedAt,
138
+ });
139
+
140
+ const ctx = createMcpToolContext({
141
+ controllerHome,
142
+ profile: 'controller',
143
+ repo: repoRoot,
144
+ sessionId: `mcp-work-efficiency-${label}`,
145
+ principalId: `principal-work-efficiency-${label}`,
146
+ controllerInstanceId: owner.record.runtimeInstanceId,
147
+ }) as MultiRepositoryMcpToolContext;
148
+ return { root, controllerHome, repoRoot, repository, ctx };
149
+ }
150
+
151
+ async function timedCall(ctx: MultiRepositoryMcpToolContext, args: Record<string, unknown>): Promise<TimedCall> {
152
+ const startedAt = performance.now();
153
+ const result = await callRuntimeTool(ctx, 'rh_work', args);
154
+ const elapsedMs = Math.round((performance.now() - startedAt) * 100) / 100;
155
+ if (!result) throw new Error('rh_work returned no benchmark result');
156
+ const value = (result.structuredContent ?? JSON.parse(result.content?.[0]?.text ?? '{}')) as Record<string, any>;
157
+ return { elapsedMs, value };
158
+ }
159
+
160
+ async function runFlow(mode: FlowSample['mode'], sample: number): Promise<FlowSample> {
161
+ const label = `${mode}-${sample}-${Date.now()}`;
162
+ const fx = createFixture(label);
163
+ const wallStartedAt = performance.now();
164
+ let controllerCalls = 0;
165
+ let processWaits = 0;
166
+ try {
167
+ const started = await timedCall(fx.ctx, {
168
+ repo_id: fx.repository.repoId,
169
+ operation: 'start',
170
+ objective: `Benchmark ${mode} work lifecycle`,
171
+ scope_clear: true,
172
+ expected_files: 1,
173
+ expected_changed_lines: 1,
174
+ requires_recovery: true,
175
+ allowed_paths: ['README.md'],
176
+ check_ids: ['package:check:bench'],
177
+ constraints: { workspaceMode: 'isolated' },
178
+ request_id: `work-efficiency-start-${label}`,
179
+ });
180
+ controllerCalls += 1;
181
+ const workId = String(started.value.data?.work?.workId ?? '');
182
+ if (!workId) throw new Error('benchmark Work was not created');
183
+ const store = { controllerHome: fx.controllerHome, repoId: fx.repository.repoId };
184
+ const contract = getWorkContract(store, workId);
185
+ if (!contract?.worktreeRef) throw new Error('benchmark Work has no managed worktree');
186
+ writeFileSync(join(contract.worktreeRef, 'README.md'), `fixture\n${mode}\n`);
187
+
188
+ const verifyArgs = {
189
+ repo_id: fx.repository.repoId,
190
+ operation: 'verify',
191
+ work_id: workId,
192
+ check_id: 'package:check:bench',
193
+ request_id: `work-efficiency-verify-${label}`,
194
+ };
195
+ const verifySubmit = await timedCall(fx.ctx, verifyArgs);
196
+ controllerCalls += 1;
197
+ const processId = String(verifySubmit.value.data?.verification?.processId ?? '');
198
+ if (!processId) throw new Error('benchmark verification did not return a Process id');
199
+ const waitStartedAt = performance.now();
200
+ await waitForProcess(fx.controllerHome, fx.repository.repoId, processId, { timeoutMs: 10_000 });
201
+ const verifyWaitMs = Math.round((performance.now() - waitStartedAt) * 100) / 100;
202
+ processWaits += 1;
203
+
204
+ const verifyReattach = await timedCall(fx.ctx, verifyArgs);
205
+ controllerCalls += 1;
206
+ const verificationOutcome = String(verifyReattach.value.data?.verification?.outcome ?? '');
207
+ const verificationNextStep = typeof verifyReattach.value.data?.nextStep === 'string'
208
+ ? verifyReattach.value.data.nextStep
209
+ : undefined;
210
+ if (verificationOutcome !== 'valid_pass') throw new Error(`benchmark verification outcome: ${verificationOutcome}`);
211
+
212
+ let continueMs = 0;
213
+ if (mode === 'legacy_ceremony') {
214
+ const continued = await timedCall(fx.ctx, {
215
+ repo_id: fx.repository.repoId,
216
+ operation: 'continue',
217
+ work_id: workId,
218
+ });
219
+ controllerCalls += 1;
220
+ continueMs = continued.elapsedMs;
221
+ if (continued.value.data?.nextStep !== 'finalize') throw new Error('legacy ceremony did not reach finalize');
222
+ }
223
+
224
+ const finalized = await timedCall(fx.ctx, {
225
+ repo_id: fx.repository.repoId,
226
+ operation: 'finalize',
227
+ work_id: workId,
228
+ });
229
+ controllerCalls += 1;
230
+ const finalStatus = String(finalized.value.data?.finalStatus ?? '');
231
+ const cleanupComplete = !existsSync(contract.worktreeRef);
232
+ const totalMs = Math.round((performance.now() - wallStartedAt) * 100) / 100;
233
+ return {
234
+ mode,
235
+ sample,
236
+ ok: finalStatus === 'completed' && cleanupComplete,
237
+ controllerCalls,
238
+ processWaits,
239
+ startMs: started.elapsedMs,
240
+ verifySubmitMs: verifySubmit.elapsedMs,
241
+ verifyWaitMs,
242
+ verifyReattachMs: verifyReattach.elapsedMs,
243
+ continueMs,
244
+ finalizeMs: finalized.elapsedMs,
245
+ totalMs,
246
+ verificationNextStep,
247
+ finalStatus,
248
+ cleanupComplete,
249
+ };
250
+ } finally {
251
+ clearRuntimeWriteClaimForTests();
252
+ rmSync(fx.root, { recursive: true, force: true });
253
+ }
254
+ }
255
+
256
+ function percentile(values: number[], p: number): number {
257
+ if (values.length === 0) return 0;
258
+ const sorted = [...values].sort((a, b) => a - b);
259
+ const index = Math.min(sorted.length - 1, Math.ceil(sorted.length * p) - 1);
260
+ return Math.round((sorted[Math.max(0, index)] ?? 0) * 100) / 100;
261
+ }
262
+
263
+ function summarize(samples: FlowSample[]) {
264
+ return {
265
+ count: samples.length,
266
+ allOk: samples.every((sample) => sample.ok),
267
+ controllerCalls: samples[0]?.controllerCalls ?? 0,
268
+ processWaits: samples[0]?.processWaits ?? 0,
269
+ totalMs: {
270
+ p50: percentile(samples.map((sample) => sample.totalMs), 0.5),
271
+ p95: percentile(samples.map((sample) => sample.totalMs), 0.95),
272
+ },
273
+ startMs: { p50: percentile(samples.map((sample) => sample.startMs), 0.5), p95: percentile(samples.map((sample) => sample.startMs), 0.95) },
274
+ verifyWallMs: {
275
+ p50: percentile(samples.map((sample) => sample.verifySubmitMs + sample.verifyWaitMs + sample.verifyReattachMs), 0.5),
276
+ p95: percentile(samples.map((sample) => sample.verifySubmitMs + sample.verifyWaitMs + sample.verifyReattachMs), 0.95),
277
+ },
278
+ continueMs: { p50: percentile(samples.map((sample) => sample.continueMs), 0.5), p95: percentile(samples.map((sample) => sample.continueMs), 0.95) },
279
+ finalizeMs: { p50: percentile(samples.map((sample) => sample.finalizeMs), 0.5), p95: percentile(samples.map((sample) => sample.finalizeMs), 0.95) },
280
+ };
281
+ }
282
+
283
+ async function main(): Promise<void> {
284
+ const sampleCount = Math.min(argNumber('--samples', 3), 10);
285
+ const sourceHeadBefore = git(process.cwd(), ['rev-parse', 'HEAD']);
286
+ const streamlined: FlowSample[] = [];
287
+ const legacy: FlowSample[] = [];
288
+
289
+ for (let sample = 1; sample <= sampleCount; sample += 1) {
290
+ if (sample % 2 === 1) {
291
+ streamlined.push(await runFlow('streamlined', sample));
292
+ legacy.push(await runFlow('legacy_ceremony', sample));
293
+ } else {
294
+ legacy.push(await runFlow('legacy_ceremony', sample));
295
+ streamlined.push(await runFlow('streamlined', sample));
296
+ }
297
+ }
298
+
299
+ const sourceHeadAfter = git(process.cwd(), ['rev-parse', 'HEAD']);
300
+ const streamlinedSummary = summarize(streamlined);
301
+ const legacySummary = summarize(legacy);
302
+ const result = {
303
+ schemaVersion: 1,
304
+ benchmark: 'work-efficiency',
305
+ revision: sourceHeadAfter,
306
+ generatedAt: new Date().toISOString(),
307
+ sampleCount,
308
+ methodology: 'Real rh_work start + managed Check Process + authoritative reattach + finalize on isolated temporary repositories. Legacy comparison adds only the mechanical continue call.',
309
+ streamlined: streamlinedSummary,
310
+ legacyCeremony: legacySummary,
311
+ productivity: {
312
+ controllerCallsSavedPerWork: legacySummary.controllerCalls - streamlinedSummary.controllerCalls,
313
+ controlRoundTripReductionRatio: legacySummary.controllerCalls > 0
314
+ ? Math.round(((legacySummary.controllerCalls - streamlinedSummary.controllerCalls) / legacySummary.controllerCalls) * 10_000) / 10_000
315
+ : 0,
316
+ measuredContinueCeremonyMsP50: legacySummary.continueMs.p50,
317
+ totalWallClockDeltaMsP50: Math.round((legacySummary.totalMs.p50 - streamlinedSummary.totalMs.p50) * 100) / 100,
318
+ },
319
+ acceptance: {
320
+ sourceCheckoutHeadStable: sourceHeadBefore === sourceHeadAfter,
321
+ streamlinedAllOk: streamlinedSummary.allOk,
322
+ legacyAllOk: legacySummary.allOk,
323
+ streamlinedDirectsFinalPassToFinalize: streamlined.every((sample) => sample.verificationNextStep === 'finalize'),
324
+ oneControllerCallSaved: legacySummary.controllerCalls - streamlinedSummary.controllerCalls === 1,
325
+ cleanupComplete: [...streamlined, ...legacy].every((sample) => sample.cleanupComplete),
326
+ },
327
+ samples: { streamlined, legacyCeremony: legacy },
328
+ };
329
+ const allAccepted = Object.values(result.acceptance).every(Boolean);
330
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
331
+ if (!allAccepted) process.exitCode = 1;
332
+ }
333
+
334
+ await main();
@@ -266,7 +266,7 @@ Use the captured planning output below as the execution source of truth.
266
266
  ### Trade-offs
267
267
  | Option | Pros | Cons | Decision |
268
268
  |--------|------|------|----------|
269
- | Captured plan | Preserves the approved Forge /plan, Codex Plan, or optional external planning decision | Requires the captured text to be concrete enough to execute | Use |
269
+ | Captured plan | Preserves the approved Codex Plan or Waza think decision | Requires the captured text to be concrete enough to execute | Use |
270
270
 
271
271
  ## Detailed Design
272
272
  ### File Changes
@@ -302,8 +302,8 @@ See captured planning output.
302
302
 
303
303
  - **State/progress path**: \`${plan_file}\` task breakdown, \`tasks/todos.md\` deferred-goal ledger, \`tasks/contracts/${artifact_stem}.contract.md\`, \`tasks/reviews/${artifact_stem}.review.md\`, and \`tasks/notes/${artifact_stem}.notes.md\`
304
304
  - **Verification evidence**: \`.ai/harness/checks/latest.json\`, \`.ai/harness/runs/\`, and the commands named in the captured planning output
305
- - **Evaluator rubric**: \`tasks/reviews/${artifact_stem}.review.md\` must record a passing Forge /review recommendation
306
- - **Stop condition**: all task breakdown items are complete, sprint verification passes, and the review recommends pass
305
+ - **Impact review**: after direct checks, reassess user intent, affected domains, downstream consumers, state transitions, and residual risks
306
+ - **Stop condition**: all task breakdown items are complete and sprint verification reports direct checks plus declared scope passing
307
307
  - **Rollback surface**: before execution remove \`${plan_file}\`; after execution revert branch \`codex/${slug}\` or the generated task artifacts
308
308
 
309
309
  ## Captured Planning Output
@@ -1,18 +1,17 @@
1
1
  #!/bin/bash
2
2
  set -euo pipefail
3
3
 
4
- if command -v bun >/dev/null 2>&1; then
4
+ if command -v node >/dev/null 2>&1; then
5
+ RUNTIME_BIN="$(command -v node)"
6
+ elif command -v bun >/dev/null 2>&1; then
5
7
  RUNTIME_BIN="$(command -v bun)"
6
8
  elif [[ -x "${HOME}/.bun/bin/bun" ]]; then
7
9
  RUNTIME_BIN="${HOME}/.bun/bin/bun"
8
- elif command -v node >/dev/null 2>&1; then
9
- RUNTIME_BIN="$(command -v node)"
10
10
  else
11
- echo "check-agent-tooling.sh requires bun or node" >&2
11
+ echo "check-agent-tooling.sh requires node or bun" >&2
12
12
  exit 1
13
13
  fi
14
14
 
15
- export FORGE_TOOLING_PATH_SNAPSHOT="${PATH:-}"
16
15
  exec "$RUNTIME_BIN" - "$@" <<'NODE_EOF'
17
16
  const fs = require("fs");
18
17
  const crypto = require("crypto");
@@ -77,7 +76,6 @@ const WAZA_RAW_BASE_URL = "https://raw.githubusercontent.com/tw93/Waza/main";
77
76
  const WAZA_MANAGED_SKILLS = ["think", "hunt", "check", "health"];
78
77
  const WAZA_SHARED_RULES = ["anti-patterns.md", "chinese.md", "durable-context.md", "english.md"];
79
78
  const CODEX_AUTOMATION_SKILLS = ["health", "check", "mermaid"];
80
- const SKILLS_CLI_TIMEOUT_MS = 5000;
81
79
  const CODEGRAPH_PACKAGE = "@colbymchenry/codegraph";
82
80
  const CODEGRAPH_GLOBAL_INSTALL_COMMAND = `bun add -g ${CODEGRAPH_PACKAGE} && forge tools configure codegraph --target codex --location global`;
83
81
  const GBRAIN_INSTALL_COMMAND = "bun install -g github:garrytan/gbrain";
@@ -140,21 +138,7 @@ function fileIsExecutable(filePath) {
140
138
 
141
139
  function detectTimeoutBin() {
142
140
  if (timeoutBin !== undefined) return timeoutBin;
143
- const candidate = resolvePathCommand("timeout");
144
- if (!candidate) {
145
- timeoutBin = "";
146
- return timeoutBin;
147
- }
148
-
149
- const capability = spawnSync(candidate, ["--version"], {
150
- encoding: "utf8",
151
- timeout: 500,
152
- env: process.env,
153
- });
154
- const output = `${capability.stdout || ""}\n${capability.stderr || ""}`;
155
- timeoutBin = capability.status === 0 && /GNU coreutils|coreutils/i.test(output)
156
- ? candidate
157
- : "";
141
+ timeoutBin = resolvePathCommand("timeout") || "";
158
142
  return timeoutBin;
159
143
  }
160
144
 
@@ -705,7 +689,7 @@ function detectWaza() {
705
689
  const skillLock = readJson(skillLockPath);
706
690
  const skillsBin = resolvePathCommand("skills");
707
691
  const skillsResult = skillsBin
708
- ? run(skillsBin, ["ls", "-g", "--json"], { timeoutMs: SKILLS_CLI_TIMEOUT_MS })
692
+ ? run(skillsBin, ["ls", "-g", "--json"], { timeoutMs: 1500 })
709
693
  : { ok: false, status: null, stdout: "", stderr: "", error: "skills CLI is not installed", timed_out: false };
710
694
  const skillItems = skillsResult.ok ? parseJson(skillsResult.stdout) || [] : [];
711
695
  const wazaEntries = Object.entries(skillLock?.skills || {}).filter(([, meta]) => meta?.source === WAZA_SOURCE_REPO);
@@ -1178,7 +1162,7 @@ function parseCodeGraphProjectStatus(output) {
1178
1162
  }
1179
1163
 
1180
1164
  function resolvePathCommand(command) {
1181
- const pathValue = process.env.FORGE_TOOLING_PATH_SNAPSHOT || process.env.PATH || "";
1165
+ const pathValue = process.env.PATH || "";
1182
1166
  for (const dir of pathValue.split(path.delimiter)) {
1183
1167
  if (!dir) continue;
1184
1168
  const candidate = path.join(dir, command);
@@ -1203,18 +1187,7 @@ function codeGraphPlatformPackageName() {
1203
1187
 
1204
1188
  function codeGraphPlatformBundleBin() {
1205
1189
  if (process.platform === "win32") return null;
1206
- const direct = path.join(REPO_ROOT, "node_modules", codeGraphPlatformPackageName(), "bin", "codegraph");
1207
- if (fileIsExecutable(direct)) return direct;
1208
- // Git worktrees commonly reuse the canonical checkout's dependencies. Resolve
1209
- // the platform package through Node/Bun module lookup instead of declaring the
1210
- // bundled Runtime missing just because this worktree has no local node_modules.
1211
- try {
1212
- const packageJson = require.resolve(`${codeGraphPlatformPackageName()}/package.json`, { paths: [REPO_ROOT] });
1213
- const resolved = path.join(path.dirname(packageJson), "bin", "codegraph");
1214
- return fileIsExecutable(resolved) ? resolved : direct;
1215
- } catch {
1216
- return direct;
1217
- }
1190
+ return path.join(REPO_ROOT, "node_modules", codeGraphPlatformPackageName(), "bin", "codegraph");
1218
1191
  }
1219
1192
 
1220
1193
  function resolveCodeGraphBinary() {