@moretea-labs/forge 1.5.0-rc.1 → 1.5.1

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 (264) hide show
  1. package/AGENTS.md +9 -11
  2. package/CHANGELOG.md +27 -1
  3. package/CLAUDE.md +8 -10
  4. package/DESIGN.md +278 -0
  5. package/README.md +70 -90
  6. package/README.zh-CN.md +52 -55
  7. package/SKILL.md +8 -11
  8. package/THIRD_PARTY_NOTICES.md +9 -3
  9. package/assets/branding/README.md +4 -2
  10. package/assets/hooks/lib/workflow-state.sh +19 -18
  11. package/assets/hooks/post-edit-guard.sh +6 -75
  12. package/assets/hooks/prompt-guard.sh +24 -12
  13. package/assets/hooks/session-start-context.sh +17 -17
  14. package/assets/hooks/stop-orchestrator.sh +2 -2
  15. package/assets/partials/04-project-structure.partial.md +6 -6
  16. package/assets/partials/05-workflow.partial.md +6 -6
  17. package/assets/partials/07-footer.partial.md +1 -1
  18. package/assets/partials/08-orchestration.partial.md +2 -2
  19. package/assets/partials-agents/02-operating-mode.partial.md +5 -5
  20. package/assets/partials-agents/03-orchestration.partial.md +3 -3
  21. package/assets/partials-agents/04-task-protocol.partial.md +3 -3
  22. package/assets/partials-agents/08-deep-docs.partial.md +1 -1
  23. package/assets/reference-configs/agentic-development-flow.md +49 -86
  24. package/assets/reference-configs/external-tooling.md +21 -61
  25. package/assets/reference-configs/handoff-protocol.md +25 -20
  26. package/assets/reference-configs/harness-overview.md +8 -8
  27. package/assets/skill-version.json +2 -2
  28. package/assets/templates/helpers/archive-workflow.sh +0 -1
  29. package/assets/templates/helpers/capture-plan.sh +3 -3
  30. package/assets/templates/helpers/check-task-workflow.sh +2 -2
  31. package/assets/templates/helpers/codex-handoff-resume.sh +5 -5
  32. package/assets/templates/helpers/ensure-task-workflow.sh +37 -35
  33. package/assets/templates/helpers/new-plan.sh +1 -1
  34. package/assets/templates/helpers/plan-to-todo.sh +2 -2
  35. package/assets/templates/helpers/prepare-codex-handoff.sh +2 -2
  36. package/assets/templates/helpers/prepare-handoff.sh +9 -9
  37. package/assets/templates/helpers/refresh-current-status.sh +2 -2
  38. package/assets/templates/helpers/ship-worktrees.sh +1 -1
  39. package/assets/templates/helpers/sprint-backlog.sh +1 -1
  40. package/assets/templates/helpers/verify-sprint.sh +7 -7
  41. package/assets/templates/helpers/workstream-sync.sh +1 -1
  42. package/assets/templates/plan.template.md +1 -1
  43. package/assets/workflow-contract.v1.json +6 -3
  44. package/docs/architecture/current/README.md +10 -9
  45. package/docs/architecture/current/approved-target-architecture.zh-CN.md +2 -2
  46. package/docs/architecture/current/architecture-invariants.md +2 -2
  47. package/docs/architecture/current/automation-and-schedule-engine.md +15 -15
  48. package/docs/architecture/current/codegraph-context-provider.md +2 -2
  49. package/docs/architecture/current/control-plane-authority-inventory.md +12 -0
  50. package/docs/architecture/current/dispatch-and-agent-strategy.md +11 -11
  51. package/docs/architecture/current/entity-model.md +0 -27
  52. package/docs/architecture/current/failure-recovery.md +0 -24
  53. package/docs/architecture/current/governance.md +1 -1
  54. package/docs/architecture/current/implementation-status.md +1 -1
  55. package/docs/architecture/current/legacy-governance.md +58 -0
  56. package/docs/architecture/current/multi-repository-execution.md +1 -1
  57. package/docs/architecture/current/peer-supercontroller-runtime.md +1 -1
  58. package/docs/architecture/current/personal-assistant-plugin-baseline.md +4 -5
  59. package/docs/architecture/current/scheduler-and-resource-claims.md +0 -10
  60. package/docs/architecture/current/target-requirements-traceability.md +2 -2
  61. package/docs/architecture/current/thin-harness-governance-policy.md +1 -1
  62. package/docs/architecture/current/thin-harness-v1.md +9 -11
  63. package/docs/architecture/domains/runtime-harness.md +1 -1
  64. package/docs/forge-autonomous-goal-loop.md +3 -1
  65. package/docs/forge-chatgpt-mcp-setup.md +67 -176
  66. package/docs/images/forge-banner-cn.svg +26 -1
  67. package/docs/images/forge-banner.svg +26 -1
  68. package/docs/operations/features.md +1 -1
  69. package/docs/operations/homebrew.md +3 -3
  70. package/docs/operations/mcp-tool-exposure.md +5 -5
  71. package/docs/operations/platform-support.md +45 -37
  72. package/docs/operations/platform-support.zh-CN.md +40 -38
  73. package/docs/operations/releasing.md +3 -3
  74. package/docs/operations/releasing.zh-CN.md +3 -3
  75. package/docs/operations/troubleshooting.md +11 -6
  76. package/docs/operations/troubleshooting.zh-CN.md +11 -6
  77. package/docs/public-usage-guide.md +28 -21
  78. package/docs/public-usage-guide.zh-CN.md +28 -21
  79. package/docs/tutorials/01-install-and-start.md +58 -35
  80. package/docs/tutorials/01-install-and-start.zh-CN.md +58 -35
  81. package/docs/tutorials/02-connect-chatgpt.md +118 -46
  82. package/docs/tutorials/02-connect-chatgpt.zh-CN.md +119 -45
  83. package/docs/wiki/Architecture.md +1 -1
  84. package/docs/wiki/Installation.md +2 -2
  85. package/docs/wiki/Quick-Start.md +1 -1
  86. package/docs/wiki/Work-Lifecycle.md +1 -1
  87. package/install.ps1 +4 -5
  88. package/install.sh +4 -6
  89. package/package.json +15 -5
  90. package/scripts/archive-workflow.sh +0 -1
  91. package/scripts/benchmark-thin-harness-mcp-e2e.ts +27 -14
  92. package/scripts/build-controller-ui.ts +28 -0
  93. package/scripts/capture-plan.sh +4 -4
  94. package/scripts/check-agent-tooling.sh +12 -1
  95. package/scripts/check-platform-support.mjs +2 -2
  96. package/scripts/check-public-docs.sh +16 -5
  97. package/scripts/check-release-readiness.sh +5 -11
  98. package/scripts/check-runtime-architecture.mjs +14 -22
  99. package/scripts/check-tarball-install-smoke.sh +3 -2
  100. package/scripts/check-task-workflow.sh +2 -2
  101. package/scripts/codex-handoff-resume.sh +5 -5
  102. package/scripts/create-project-dirs.sh +3 -3
  103. package/scripts/ensure-task-workflow.sh +45 -35
  104. package/scripts/init-project.sh +4 -4
  105. package/scripts/install-desktop-operator-registration.ts +2 -2
  106. package/scripts/lib/project-init-lib.sh +46 -44
  107. package/scripts/migrate-project-template.sh +7 -4
  108. package/scripts/new-plan.sh +1 -1
  109. package/scripts/plan-to-todo.sh +2 -2
  110. package/scripts/prepare-codex-handoff.sh +2 -2
  111. package/scripts/prepare-handoff.sh +9 -9
  112. package/scripts/refresh-current-status.sh +2 -2
  113. package/scripts/setup-plugins.sh +3 -3
  114. package/scripts/ship-worktrees.sh +1 -1
  115. package/scripts/sprint-backlog.sh +5 -5
  116. package/scripts/sync-codex-installed-copies.sh +2 -3
  117. package/scripts/verify-sprint.sh +7 -7
  118. package/scripts/workstream-sync.sh +1 -1
  119. package/src/cli/chatgpt-browser/bridge-extension.ts +1 -1
  120. package/src/cli/chatgpt-browser/bridge-provider.ts +29 -0
  121. package/src/cli/chatgpt-browser/file-policy.ts +3 -1
  122. package/src/cli/commands/chatgpt.ts +51 -0
  123. package/src/cli/commands/doctor.ts +1 -1
  124. package/src/cli/commands/init-hook.ts +213 -70
  125. package/src/cli/commands/init.ts +5 -6
  126. package/src/cli/commands/mcp.ts +31 -5
  127. package/src/cli/commands/runtime.ts +61 -8
  128. package/src/cli/commands/setup-profile.ts +472 -0
  129. package/src/cli/controller/check-runner.ts +20 -3
  130. package/src/cli/controller/codex-continuation.ts +4 -7
  131. package/src/cli/controller/context-pack.ts +118 -14
  132. package/src/cli/controller/operational-plan.ts +4 -4
  133. package/src/cli/controller/task-ledger.ts +10 -10
  134. package/src/cli/controller/work-mode.ts +6 -13
  135. package/src/cli/index.ts +14 -35
  136. package/src/cli/local-bridge/connector-freshness.ts +1 -1
  137. package/src/cli/local-bridge/console-assets.ts +17 -0
  138. package/src/cli/local-bridge/console-automations.ts +160 -0
  139. package/src/cli/local-bridge/dashboard.ts +8 -1303
  140. package/src/cli/local-bridge/facade-api.ts +16 -7
  141. package/src/cli/local-bridge/frontend/src/App.tsx +10 -0
  142. package/src/cli/local-bridge/frontend/src/components/Button.tsx +1 -0
  143. package/src/cli/local-bridge/frontend/src/components/DetailPane.tsx +3 -0
  144. package/src/cli/local-bridge/frontend/src/components/SearchField.tsx +1 -0
  145. package/src/cli/local-bridge/frontend/src/components/SectionHeader.tsx +1 -0
  146. package/src/cli/local-bridge/frontend/src/components/Segmented.tsx +1 -0
  147. package/src/cli/local-bridge/frontend/src/components/StatusText.tsx +3 -0
  148. package/src/cli/local-bridge/frontend/src/design/icons.tsx +11 -0
  149. package/src/cli/local-bridge/frontend/src/design/tokens.css +8 -0
  150. package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +3 -0
  151. package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +4 -0
  152. package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +3 -0
  153. package/src/cli/local-bridge/frontend/src/features/repositories/RepositoriesView.tsx +2 -0
  154. package/src/cli/local-bridge/frontend/src/features/settings/SettingsView.tsx +2 -0
  155. package/src/cli/local-bridge/frontend/src/features/system/SystemView.tsx +2 -0
  156. package/src/cli/local-bridge/frontend/src/features/work/WorkView.tsx +3 -0
  157. package/src/cli/local-bridge/frontend/src/lib/api.ts +23 -0
  158. package/src/cli/local-bridge/frontend/src/lib/format.ts +4 -0
  159. package/src/cli/local-bridge/frontend/src/lib/routes.ts +7 -0
  160. package/src/cli/local-bridge/frontend/src/main.tsx +1 -0
  161. package/src/cli/local-bridge/frontend/src/shell/AppShell.tsx +1 -0
  162. package/src/cli/local-bridge/frontend/src/shell/CommandBar.tsx +2 -0
  163. package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +3 -0
  164. package/src/cli/local-bridge/frontend/src/styles.css +12 -0
  165. package/src/cli/local-bridge/frontend/src/types.ts +14 -0
  166. package/src/cli/local-bridge/frontend/src/vite-env.d.ts +1 -0
  167. package/src/cli/local-bridge/frontend/vite.config.ts +27 -0
  168. package/src/cli/local-bridge/server.ts +45 -0
  169. package/src/cli/local-bridge/ui-dist/app.css +1 -0
  170. package/src/cli/local-bridge/ui-dist/app.js +11094 -0
  171. package/src/cli/mcp/auth.ts +2 -0
  172. package/src/cli/mcp/instructions.ts +3 -3
  173. package/src/cli/mcp/legacy-tool-service.ts +27 -23
  174. package/src/cli/mcp/multi-repository.ts +2 -0
  175. package/src/cli/mcp/policy.ts +7 -5
  176. package/src/cli/mcp/repository-tools.ts +53 -14
  177. package/src/cli/mcp/server.ts +5 -10
  178. package/src/cli/mcp/setup.ts +220 -276
  179. package/src/cli/mcp/tool-capability-cache.ts +1 -1
  180. package/src/cli/mcp/toolset-names.ts +1 -1
  181. package/src/cli/mcp/toolset.ts +0 -1
  182. package/src/cli/mcp/transports/http.ts +51 -4
  183. package/src/cli/repositories/branch-name-policy.ts +0 -7
  184. package/src/cli/repositories/controller-home.ts +110 -3
  185. package/src/cli/repositories/safe-patch.ts +1 -1
  186. package/src/cli/repositories/selected-path-actions.ts +26 -24
  187. package/src/core/adoption/gitignore-plan.ts +2 -3
  188. package/src/core/adoption/plan.ts +4 -1
  189. package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +556 -0
  190. package/src/runtime/control-plane/execution/work-handle-store.ts +128 -1
  191. package/src/runtime/control-plane/execution/work-validation-reconciler.ts +277 -0
  192. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +169 -0
  193. package/src/runtime/control-plane/facade/capability-registry.ts +0 -10
  194. package/src/runtime/control-plane/facade/handoff-inbox-store.ts +44 -25
  195. package/src/runtime/control-plane/facade/suggested-actions.ts +7 -1
  196. package/src/runtime/control-plane/facade/types.ts +0 -1
  197. package/src/runtime/control-plane/global-scheduler/scheduler.ts +30 -8
  198. package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +114 -0
  199. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +175 -0
  200. package/src/runtime/control-plane/launcher/launch-reservation-store.ts +161 -0
  201. package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +64 -0
  202. package/src/runtime/control-plane/launcher/thin-launcher.ts +117 -24
  203. package/src/runtime/control-plane/routing/route-policy.ts +14 -14
  204. package/src/runtime/control-plane/runtime-cleanup.ts +0 -1
  205. package/src/runtime/evidence/event-ledger.ts +1 -1
  206. package/src/runtime/{workflow/campaigns/workspace.ts → execution/managed-workspace.ts} +41 -43
  207. package/src/runtime/execution/process-runtime/check-facade.ts +6 -0
  208. package/src/runtime/execution/process-runtime/check-result.ts +45 -0
  209. package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +42 -16
  210. package/src/runtime/execution/process-runtime/command-facade.ts +4 -2
  211. package/src/runtime/execution/process-runtime/gc.ts +1 -1
  212. package/src/runtime/execution/process-runtime/index.ts +3 -0
  213. package/src/runtime/execution/process-runtime/interactive-admission.ts +14 -5
  214. package/src/runtime/execution/process-runtime/persisted-check.ts +285 -0
  215. package/src/runtime/execution/process-runtime/resource-claims.ts +30 -0
  216. package/src/runtime/execution/process-runtime/runtime.ts +18 -1
  217. package/src/runtime/execution/process-runtime/store.ts +1 -19
  218. package/src/runtime/execution/process-runtime/types.ts +4 -0
  219. package/src/runtime/execution/thin-harness/execution-router.ts +0 -1
  220. package/src/runtime/execution/thin-harness/fast-executor.ts +1 -1
  221. package/src/runtime/execution/thin-harness/lightweight-lanes.ts +1 -2
  222. package/src/runtime/execution/thin-harness/types.ts +0 -1
  223. package/src/runtime/execution/workers/executor.ts +1 -1
  224. package/src/runtime/gateway/mcp/execution-tools.ts +1 -1
  225. package/src/runtime/gateway/mcp/persisted-check-process.ts +3 -255
  226. package/src/runtime/gateway/mcp/process-tools.ts +16 -3
  227. package/src/runtime/gateway/mcp/resource-policy.ts +0 -9
  228. package/src/runtime/gateway/mcp/router.ts +117 -182
  229. package/src/runtime/gateway/mcp/runtime-tools.ts +331 -409
  230. package/src/runtime/gateway/mcp/work-validation-reconciler.ts +1 -219
  231. package/src/runtime/plugins/browser-adapter.ts +5 -0
  232. package/src/runtime/plugins/desktop-operator-registration.ts +1 -1
  233. package/src/runtime/plugins/store.ts +14 -6
  234. package/src/runtime/plugins/types.ts +1 -1
  235. package/src/runtime/projections/materialized-view.ts +1 -23
  236. package/src/runtime/recovery/maintenance-executor.ts +9 -0
  237. package/src/runtime/resources/ownership.ts +0 -1
  238. package/src/runtime/root/gateway-adapter.ts +2 -0
  239. package/src/runtime/root/mcp-transport.ts +10 -2
  240. package/src/runtime/root/package-connector-service.ts +136 -0
  241. package/src/runtime/root/package-runtime-release.ts +161 -0
  242. package/src/runtime/root/package-runtime-service.ts +185 -0
  243. package/src/runtime/root/release-materialize.ts +19 -0
  244. package/src/runtime/root/runtime.ts +2 -1
  245. package/src/runtime/root/scheduler.ts +5 -0
  246. package/src/runtime/root/service.ts +18 -5
  247. package/src/runtime/standalone-recovery/core.ts +65 -16
  248. package/src/runtime/workflow/findings/store.ts +145 -106
  249. package/src/runtime/workflow/findings/types.ts +22 -0
  250. package/src/runtime/workflow/schedules/engine.ts +132 -2
  251. package/src/runtime/workflow/schedules/pending-activation.ts +139 -0
  252. package/src/runtime/workflow/schedules/work-continuation.ts +218 -0
  253. package/docs/CHANGELOG.md +0 -978
  254. package/docs/README.zh-CN.md +0 -58
  255. package/scripts/smoke-chatgpt-supervised-automation.ts +0 -208
  256. package/src/cli/commands/controller.ts +0 -680
  257. package/src/runtime/workflow/campaigns/cleanup.ts +0 -263
  258. package/src/runtime/workflow/campaigns/engine.ts +0 -112
  259. package/src/runtime/workflow/campaigns/normalize.ts +0 -100
  260. package/src/runtime/workflow/campaigns/review.ts +0 -315
  261. package/src/runtime/workflow/campaigns/store.ts +0 -526
  262. package/src/runtime/workflow/campaigns/supervisor.ts +0 -112
  263. package/src/runtime/workflow/campaigns/types.ts +0 -290
  264. /package/src/runtime/{workflow/campaigns → execution}/workspace-agent.ts +0 -0
package/install.sh CHANGED
@@ -13,7 +13,6 @@ HOME_DIR="${HOME:-}"
13
13
  [ -n "$HOME_DIR" ] || die "HOME is not set"
14
14
  BUN_INSTALL_DIR="${BUN_INSTALL:-$HOME_DIR/.bun}"
15
15
 
16
- ensure_git() { has_command git || die "Git is required. Install Git and reopen the terminal."; }
17
16
  ensure_node() {
18
17
  has_command node || die "Node.js 20.10 or newer is required because the published Forge launcher uses Node."
19
18
  node -e 'const [major, minor] = process.versions.node.split(".").map(Number); process.exit(major > 20 || (major === 20 && minor >= 10) ? 0 : 1)' \
@@ -51,16 +50,15 @@ verify_forge() {
51
50
  }
52
51
 
53
52
  if [ "${FORGE_DRY_RUN:-0}" = "1" ]; then
54
- log "DRY RUN: would require Git and Node.js 20.10 or newer, choose runtime (${INSTALL_RUNTIME}), install ${PACKAGE_NAME}@${PACKAGE_VERSION}, and verify the Forge CLI."
53
+ log "DRY RUN: would require Node.js 20.10 or newer and npm/Bun, install ${PACKAGE_NAME}@${PACKAGE_VERSION}, and verify the Forge CLI. Git is optional until repository features are enabled."
55
54
  exit 0
56
55
  fi
57
- ensure_git
58
56
  ensure_node
59
57
  runtime="$(choose_runtime)"
60
58
  install_forge "$runtime"
61
59
  verify_forge
62
60
  log ""
63
61
  log "Next:"
64
- log " forge install --no-cli"
65
- log " forge doctor"
66
- log " forge adopt --repo /path/to/your-project --dry-run"
62
+ log " forge setup"
63
+ log ""
64
+ log "Git is only needed when you enable repository/software-work features."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moretea-labs/forge",
3
- "version": "1.5.0-rc.1",
3
+ "version": "1.5.1",
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",
@@ -30,6 +30,7 @@
30
30
  },
31
31
  "files": [
32
32
  "LICENSE",
33
+ "DESIGN.md",
33
34
  "CHANGELOG.md",
34
35
  "CONTRIBUTING.md",
35
36
  "SECURITY.md",
@@ -78,6 +79,9 @@
78
79
  "bun": ">=1.0.0"
79
80
  },
80
81
  "scripts": {
82
+ "build:controller-ui": "bun scripts/build-controller-ui.ts",
83
+ "check:controller-ui": "bun scripts/build-controller-ui.ts --check",
84
+ "check:design": "npx -y @google/design.md@0.4.0 lint DESIGN.md",
81
85
  "benchmark:skills": "bun scripts/run-skill-evals.ts",
82
86
  "benchmark:route-session-concurrency": "bun scripts/benchmark-route-session-concurrency.ts",
83
87
  "test": "bun scripts/test-governance.ts affected",
@@ -130,24 +134,30 @@
130
134
  "check:forge-runtime": "bash scripts/verify-forge-runtime.sh",
131
135
  "repo:registry": "bun src/cli/v81-entry.ts repo",
132
136
  "smoke:schedule-engine": "node --loader ./src/runtime/shared/node-ts-loader.mjs scripts/smoke-schedule-engine.ts",
133
- "smoke:supervised-automation": "node --loader ./src/runtime/shared/node-ts-loader.mjs scripts/smoke-chatgpt-supervised-automation.ts",
134
137
  "check:env": "node scripts/check-runtime-env.mjs",
135
138
  "test:bun": "bun -e 'console.error(\"[tests] test:bun is deprecated; running explicit test:full\")' && bun run test:full",
136
139
  "test:node-smoke": "node --test tests/node/*.test.mjs",
137
- "check:ci:portable": "FORGE_ALLOW_NODE_ONLY=1 bash scripts/check-ci.sh"
140
+ "check:ci:portable": "FORGE_ALLOW_NODE_ONLY=1 bash scripts/check-ci.sh",
141
+ "dev:controller-ui": "vite --config src/cli/local-bridge/frontend/vite.config.ts"
138
142
  },
139
143
  "devDependencies": {
140
144
  "@colbymchenry/codegraph": "1.0.1",
141
145
  "@types/bun": "latest",
142
146
  "@types/cors": "^2.8.17",
143
147
  "@types/express": "^5.0.0",
144
- "typescript": "^6.0.3"
148
+ "@types/react": "^19.2.0",
149
+ "@types/react-dom": "^19.2.0",
150
+ "@vitejs/plugin-react": "^5.2.0",
151
+ "vite": "^7.3.0"
145
152
  },
146
153
  "dependencies": {
147
154
  "@modelcontextprotocol/sdk": "^1.28.0",
148
155
  "commander": "^14.0.3",
149
156
  "express": "^5.2.1",
150
- "playwright": "^1.54.1"
157
+ "playwright": "^1.54.1",
158
+ "react": "^19.2.0",
159
+ "react-dom": "^19.2.0",
160
+ "typescript": "^6.0.3"
151
161
  },
152
162
  "packageManager": "npm@10.0.0",
153
163
  "optionalDependencies": {
@@ -283,7 +283,6 @@ fi
283
283
  plan_key="$(basename "$plan_file" .md)"
284
284
  rm -f ".claude/.plan-state/${plan_key}.todo.md.bak"
285
285
  rm -f ".claude/.plan-state/${plan_key}.task-state.json.bak"
286
- rm -f ".claude/.plan-state/${plan_key}.task-handoff.md.bak"
287
286
 
288
287
  if [[ -x "scripts/refresh-current-status.sh" ]]; then
289
288
  bash "scripts/refresh-current-status.sh" --clear --write --reason "archive-workflow" || true
@@ -36,6 +36,7 @@ import {
36
36
  resetLeaseSideEffectMetrics,
37
37
  } from '../src/runtime/resources/leases/store';
38
38
  import type { MultiRepositoryMcpToolContext } from '../src/cli/mcp/multi-repository';
39
+ import { waitForProcess } from '../src/runtime/execution/process-runtime/runtime';
39
40
 
40
41
  function git(root: string, args: string[]): void {
41
42
  const result = spawnSync('git', ['-C', root, ...args], { encoding: 'utf-8' });
@@ -104,7 +105,7 @@ interface PhaseSample {
104
105
  receiptMs: number;
105
106
  serializationMs: number;
106
107
  totalMs: number;
107
- path: 'direct' | 'fast' | 'durable' | 'reject';
108
+ path: 'direct' | 'fast' | 'process_direct' | 'process_managed' | 'durable' | 'reject';
108
109
  ok: boolean;
109
110
  executionJobDelta: number;
110
111
  localJobDelta: number;
@@ -157,7 +158,8 @@ async function dispatchMcpLike(
157
158
  // Durable accepted path (queued). Measure only accept latency; do not wait for workers.
158
159
  payload = (durableResult.structuredContent ?? {}) as Record<string, unknown>;
159
160
  const reported = String(payload.path ?? payload.mode ?? 'durable');
160
- path = reported === 'fast' || reported === 'direct' || reported === 'reject' || reported === 'durable'
161
+ path = reported === 'fast' || reported === 'direct' || reported === 'process_direct'
162
+ || reported === 'process_managed' || reported === 'reject' || reported === 'durable'
161
163
  ? reported
162
164
  : 'durable';
163
165
  queueDelayMs = thinRoutingMs;
@@ -175,7 +177,8 @@ async function dispatchMcpLike(
175
177
  operationMs = Math.round((performance.now() - opStart) * 100) / 100;
176
178
  payload = (toolResult?.structuredContent ?? {}) as Record<string, unknown>;
177
179
  const reported = String(payload.path ?? payload.mode ?? classification.path);
178
- path = reported === 'fast' || reported === 'direct' || reported === 'reject' || reported === 'durable'
180
+ path = reported === 'fast' || reported === 'direct' || reported === 'process_direct'
181
+ || reported === 'process_managed' || reported === 'reject' || reported === 'durable'
179
182
  || reported === 'durable_worker_inline'
180
183
  ? (reported === 'durable_worker_inline' ? 'durable' : reported as PhaseSample['path'])
181
184
  : classification.path;
@@ -237,6 +240,13 @@ async function sampleCase(
237
240
  };
238
241
 
239
242
  const acceptedJob = typeof payload.jobId === 'string' && payload.jobId.trim() ? 1 : 0;
243
+ const processId = typeof payload.processId === 'string' ? payload.processId.trim() : '';
244
+ // Admission latency was already captured above. Settle a managed Process before
245
+ // the next sample so a correct same-checkout resource claim is not misreported
246
+ // as a benchmark regression.
247
+ if (phases.path === 'process_managed' && processId) {
248
+ await waitForProcess(fixture.controllerHome, fixture.repository.repoId, processId, { timeoutMs: 10_000 });
249
+ }
240
250
  return {
241
251
  ...phases,
242
252
  executionJobDelta: Math.max(
@@ -394,19 +404,15 @@ async function main() {
394
404
  },
395
405
  })));
396
406
 
397
- cases.push(await runCase(fixture, 'async_command_durable', 'repository_command_execute', () => ({
398
- command: ['git', 'status', '--short'],
407
+ cases.push(await runCase(fixture, 'async_command_process_handle', 'repository_command_execute', () => ({
408
+ command: ['bun', '-e', 'await Bun.sleep(250); console.log("async-bench")'],
399
409
  apply_mode: 'async',
410
+ request_id: `mcp-e2e-async-${Date.now()}-${Math.random()}`,
400
411
  timeout_ms: 8_000,
401
412
  })));
402
413
 
403
- cases.push(await runCase(fixture, 'full_test_durable', 'repository_command_execute', () => ({
404
- command: ['bun', 'test'],
405
- timeout_ms: 120_000,
406
- })));
407
-
408
- const fastCases = cases.filter((entry) => !['async_command_durable', 'full_test_durable'].includes(entry.name));
409
- const durableCases = cases.filter((entry) => ['async_command_durable', 'full_test_durable'].includes(entry.name));
414
+ const processCases = cases.filter((entry) => entry.name === 'async_command_process_handle');
415
+ const fastCases = cases.filter((entry) => entry.name !== 'async_command_process_handle');
410
416
 
411
417
  const report = {
412
418
  schemaVersion: 1,
@@ -421,7 +427,10 @@ async function main() {
421
427
  fastZeroWorkers: fastCases.every((entry) => entry.workerSpawnCount === 0),
422
428
  fastZeroSchedulerWakes: fastCases.every((entry) => entry.schedulerWakeDelta === 0),
423
429
  fastZeroProjectionInvalidations: fastCases.every((entry) => entry.projectionInvalidationDelta === 0),
424
- durableStillRoutesDurable: durableCases.every((entry) => entry.path === 'durable' || String(entry.samples?.[0]?.path) === 'durable'),
430
+ processRuntimeAsyncAccepted: processCases.every((entry) => entry.ok && entry.path === 'process_managed'),
431
+ processRuntimeAsyncZeroExecutionJobs: processCases.every((entry) => entry.executionJobDelta === 0),
432
+ processRuntimeAsyncZeroLocalJobs: processCases.every((entry) => entry.localJobDelta === 0),
433
+ processRuntimeAsyncZeroWorkers: processCases.every((entry) => entry.workerSpawnCount === 0),
425
434
  allOk: cases.every((entry) => entry.ok),
426
435
  },
427
436
  leaseFiles: countLeaseFiles(fixture.controllerHome, fixture.repository.repoId),
@@ -465,8 +474,12 @@ async function main() {
465
474
 
466
475
  const failed = !report.acceptance.allOk
467
476
  || !report.acceptance.fastZeroExecutionJobs
477
+ || !report.acceptance.fastZeroLocalJobs
468
478
  || !report.acceptance.fastZeroWorkers
469
- || !report.acceptance.durableStillRoutesDurable;
479
+ || !report.acceptance.processRuntimeAsyncAccepted
480
+ || !report.acceptance.processRuntimeAsyncZeroExecutionJobs
481
+ || !report.acceptance.processRuntimeAsyncZeroLocalJobs
482
+ || !report.acceptance.processRuntimeAsyncZeroWorkers;
470
483
  process.exitCode = failed ? 1 : 0;
471
484
  } finally {
472
485
  rmSync(fixture.root, { recursive: true, force: true });
@@ -0,0 +1,28 @@
1
+ import { mkdtemp, readFile, rm } from 'node:fs/promises';
2
+ import { tmpdir } from 'node:os';
3
+ import { join, resolve } from 'node:path';
4
+ import { build } from 'vite';
5
+
6
+ const root = resolve(import.meta.dir, '..');
7
+ const configFile = resolve(root, 'src/cli/local-bridge/frontend/vite.config.ts');
8
+ const committedOutdir = resolve(root, 'src/cli/local-bridge/ui-dist');
9
+ const checkOnly = process.argv.includes('--check');
10
+ const outdir = checkOnly ? await mkdtemp(join(tmpdir(), 'forge-controller-ui-')) : committedOutdir;
11
+
12
+ try {
13
+ await build({ configFile, build: { outDir: outdir, emptyOutDir: true } });
14
+ if (checkOnly) {
15
+ for (const asset of ['app.js', 'app.css']) {
16
+ const [generated, committed] = await Promise.all([
17
+ readFile(resolve(outdir, asset), 'utf8'),
18
+ readFile(resolve(committedOutdir, asset), 'utf8'),
19
+ ]);
20
+ if (generated !== committed) throw new Error(`CONTROLLER_UI_BUNDLE_STALE: ${asset}; run bun run build:controller-ui`);
21
+ }
22
+ console.log('Controller UI bundle is current.');
23
+ } else {
24
+ console.log(`Controller UI built: ${resolve(outdir, 'app.js')}, ${resolve(outdir, 'app.css')}`);
25
+ }
26
+ } finally {
27
+ if (checkOnly) await rm(outdir, { recursive: true, force: true });
28
+ }
@@ -103,7 +103,7 @@ extract_task_breakdown() {
103
103
  slug=""
104
104
  title=""
105
105
  status="Draft"
106
- source_name="codex-plan-or-waza-think"
106
+ source_name="host-plan-or-forge-plan"
107
107
  route="planning"
108
108
  orchestration_kind="host-plan"
109
109
  source_ref=""
@@ -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 Codex Plan or Waza think decision | Requires the captured text to be concrete enough to execute | Use |
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 |
270
270
 
271
271
  ## Detailed Design
272
272
  ### File Changes
@@ -296,13 +296,13 @@ See captured planning output.
296
296
  ## Handoff
297
297
 
298
298
  - Checks file: \`.ai/harness/checks/latest.json\`
299
- - Session handoff: \`.ai/harness/handoff/current.md\`
299
+ - Session continuation: \`.ai/harness/session/continuation.md\`
300
300
 
301
301
  ## Evidence Contract
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 Waza /check style recommendation
305
+ - **Evaluator rubric**: \`tasks/reviews/${artifact_stem}.review.md\` must record a passing Forge /review recommendation
306
306
  - **Stop condition**: all task breakdown items are complete, sprint verification passes, and the review recommends pass
307
307
  - **Rollback surface**: before execution remove \`${plan_file}\`; after execution revert branch \`codex/${slug}\` or the generated task artifacts
308
308
 
@@ -1203,7 +1203,18 @@ function codeGraphPlatformPackageName() {
1203
1203
 
1204
1204
  function codeGraphPlatformBundleBin() {
1205
1205
  if (process.platform === "win32") return null;
1206
- return path.join(REPO_ROOT, "node_modules", codeGraphPlatformPackageName(), "bin", "codegraph");
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
+ }
1207
1218
  }
1208
1219
 
1209
1220
  function resolveCodeGraphBinary() {
@@ -42,8 +42,8 @@ for (const path of ["install.sh", "install.ps1"]) {
42
42
  requireText(path, "FORGE_INSTALL_RUNTIME");
43
43
  requireText(path, "FORGE_INSTALL_RUNTIME");
44
44
  requireText(path, "Node.js 20.10");
45
- requireText(path, "Git is required");
46
- requireText(path, "forge install --no-cli");
45
+ requireText(path, "Git is optional");
46
+ requireText(path, "forge setup");
47
47
  }
48
48
  requireText("install.sh", "npm install -g");
49
49
  requireText("install.ps1", "npm install -g");
@@ -4,6 +4,17 @@ set -euo pipefail
4
4
  ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
5
  cd "$ROOT"
6
6
 
7
+ PACKAGE_VERSION="$(node -p "require('./package.json').version")"
8
+ if [[ "$PACKAGE_VERSION" == *-rc.* ]]; then
9
+ INSTALL_SPEC='@moretea-labs/forge@next'
10
+ README_CHANNEL_EN='npm `next`'
11
+ README_CHANNEL_ZH='npm 使用 `next`'
12
+ else
13
+ INSTALL_SPEC='@moretea-labs/forge'
14
+ README_CHANNEL_EN='npm `latest`'
15
+ README_CHANNEL_ZH='npm `latest`'
16
+ fi
17
+
7
18
  required=(
8
19
  README.md README.en.md README.zh-CN.md
9
20
  CHANGELOG.md CONTRIBUTING.md SECURITY.md SUPPORT.md CODE_OF_CONDUCT.md
@@ -45,7 +56,7 @@ for path in README.md README.zh-CN.md; do
45
56
  fi
46
57
  grep -q 'Node.js 20.10' "$path" || { echo "[public-docs] missing Node baseline: $path" >&2; exit 1; }
47
58
  grep -q 'npm install -g \.' "$path" || { echo "[public-docs] missing verified source install: $path" >&2; exit 1; }
48
- grep -q '@moretea-labs/forge@next' "$path" || { echo "[public-docs] missing upcoming RC install reference: $path" >&2; exit 1; }
59
+ grep -q "$INSTALL_SPEC" "$path" || { echo "[public-docs] missing package install reference for $PACKAGE_VERSION: $path" >&2; exit 1; }
49
60
  for link in SUPPORT.md SECURITY.md CONTRIBUTING.md CHANGELOG.md docs/wiki/Home.md; do
50
61
  grep -q "$link" "$path" || { echo "[public-docs] missing $link link: $path" >&2; exit 1; }
51
62
  done
@@ -57,14 +68,14 @@ done
57
68
 
58
69
  grep -q 'docs/tutorials/01-install-and-start.md' README.md || { echo "[public-docs] English README missing tutorial link" >&2; exit 1; }
59
70
  grep -q 'docs/tutorials/01-install-and-start.zh-CN.md' README.zh-CN.md || { echo "[public-docs] Chinese README missing tutorial link" >&2; exit 1; }
60
- grep -q 'npm `next`' README.md || { echo "[public-docs] English README must state the RC npm channel" >&2; exit 1; }
61
- grep -q 'npm 使用 `next`' README.zh-CN.md || { echo "[public-docs] Chinese README must state the RC npm channel" >&2; exit 1; }
71
+ grep -q "$README_CHANNEL_EN" README.md || { echo "[public-docs] English README must state the npm channel for $PACKAGE_VERSION" >&2; exit 1; }
72
+ grep -q "$README_CHANNEL_ZH" README.zh-CN.md || { echo "[public-docs] Chinese README must state the npm channel for $PACKAGE_VERSION" >&2; exit 1; }
62
73
  grep -q 'See \[README.md\](README.md)' README.en.md || { echo "[public-docs] README.en.md must point to the maintained English README" >&2; exit 1; }
63
74
 
64
75
  for path in docs/tutorials/01-install-and-start.md docs/tutorials/01-install-and-start.zh-CN.md; do
65
76
  grep -q 'Node.js 20.10' "$path" || { echo "[public-docs] missing Node baseline: $path" >&2; exit 1; }
66
77
  grep -q 'npm install -g \.' "$path" || { echo "[public-docs] missing source install: $path" >&2; exit 1; }
67
- grep -q '@moretea-labs/forge@next' "$path" || { echo "[public-docs] missing upcoming package command: $path" >&2; exit 1; }
78
+ grep -q "$INSTALL_SPEC" "$path" || { echo "[public-docs] missing package command for $PACKAGE_VERSION: $path" >&2; exit 1; }
68
79
  done
69
80
 
70
81
  for path in docs/operations/releasing.md docs/operations/releasing.zh-CN.md; do
@@ -84,7 +95,7 @@ done
84
95
  grep -q 'npm.*primary package registry' docs/operations/releasing.md || { echo "[public-docs] npm primary registry role is unclear" >&2; exit 1; }
85
96
  grep -q 'GitHub Releases' docs/operations/releasing.md || { echo "[public-docs] GitHub Release role is unclear" >&2; exit 1; }
86
97
  grep -q 'publishConfig.provenance' docs/versioning.md || { echo "[public-docs] provenance contract is undocumented" >&2; exit 1; }
87
- grep -q 'after the first stable release' docs/operations/homebrew.md || { echo "[public-docs] Homebrew stable-only gate is unclear" >&2; exit 1; }
98
+ grep -q 'stable npm/GitHub release' docs/operations/homebrew.md || { echo "[public-docs] Homebrew stable-only gate is unclear" >&2; exit 1; }
88
99
  grep -q 'WSL2' docs/operations/platform-support.md || { echo "[public-docs] platform matrix missing WSL2" >&2; exit 1; }
89
100
  grep -q 'Windows 原生' docs/operations/platform-support.zh-CN.md || { echo "[public-docs] Chinese platform matrix missing native Windows scope" >&2; exit 1; }
90
101
  grep -q 'rh_status' docs/tutorials/02-connect-chatgpt.md || { echo "[public-docs] connector tutorial missing facade verification" >&2; exit 1; }
@@ -24,18 +24,12 @@ bun run check:public-export
24
24
 
25
25
  ARTIFACT_DIR="${FORGE_RELEASE_ARTIFACT_DIR:-$ROOT/.ai/harness/artifacts/release}"
26
26
  mkdir -p "$ARTIFACT_DIR"
27
- PACK_JSON="$ARTIFACT_DIR/pack.json"
28
- echo "[release-readiness] create one reusable tarball"
29
- npm pack --json --pack-destination "$ARTIFACT_DIR" >"$PACK_JSON"
30
- TARBALL="$(bun - "$PACK_JSON" <<'JS_EOF'
31
- const [, , path] = process.argv;
32
- const value = await Bun.file(path).json();
33
- const entry = Array.isArray(value) ? value[0] : value;
34
- if (!entry?.filename) throw new Error('npm pack did not report a filename');
35
- console.log(entry.filename);
36
- JS_EOF
37
- )"
27
+ TARBALL="$(node -e 'const p=require("./package.json"); process.stdout.write(`${p.name.replace(/^@/, "").replace(/\//g, "-")}-${p.version}.tgz`)')"
38
28
  TARBALL_PATH="$ARTIFACT_DIR/$TARBALL"
29
+ echo "[release-readiness] create one reusable tarball"
30
+ rm -f "$TARBALL_PATH"
31
+ npm pack --pack-destination "$ARTIFACT_DIR" >/dev/null
32
+ [[ -f "$TARBALL_PATH" ]] || { echo "[release-readiness] ERROR: npm pack did not create $TARBALL_PATH" >&2; exit 1; }
39
33
  printf '%s\n' "$TARBALL_PATH" >"$ARTIFACT_DIR/latest-tarball.txt"
40
34
 
41
35
  echo "[release-readiness] smoke the same tarball"
@@ -67,6 +67,7 @@ const required = [
67
67
  'src/runtime/projections/controller-context.ts',
68
68
  'src/runtime/projections/invalidation.ts',
69
69
  'src/runtime/workflow/schedules/engine.ts',
70
+ 'src/runtime/workflow/schedules/work-continuation.ts',
70
71
  'scripts/smoke-runtime-recovery.ts',
71
72
  'scripts/smoke-schedule-engine.ts',
72
73
  'src/runtime/workflow/portfolio/engine.ts',
@@ -83,7 +84,6 @@ const required = [
83
84
  'src/runtime/standalone-recovery/entry.ts',
84
85
  'src/cli/commands/init-hook.ts',
85
86
  'src/cli/commands/runtime.ts',
86
- 'src/cli/commands/controller.ts',
87
87
  'src/cli/index.ts',
88
88
  'docs/architecture/current/runtime-architecture-simplification.md',
89
89
  'docs/architecture/current/implementation-status.md',
@@ -96,6 +96,17 @@ for (const path of required) text(path);
96
96
  requireText('src/runtime/control-plane/routing/route-policy.ts', "export function decideRoute");
97
97
  requireText('src/runtime/control-plane/routing/route-policy.ts', 'inputFingerprint');
98
98
  requireText('src/runtime/control-plane/routing/route-policy.ts', 'policyVersion');
99
+ requireText('src/runtime/gateway/mcp/runtime-tools.ts', 'runPersistedCheckViaProcessRuntime({');
100
+ requireText('src/runtime/gateway/mcp/runtime-tools.ts', 'interactiveWaitMs: 0');
101
+ requireText('src/runtime/gateway/mcp/runtime-tools.ts', 'checkContentRevision');
102
+ requireText('src/runtime/gateway/mcp/runtime-tools.ts', 'observedGitHead');
103
+ forbidBetween(
104
+ 'src/runtime/gateway/mcp/runtime-tools.ts',
105
+ 'async function runFacadeVerify(',
106
+ 'export async function callRuntimeTool',
107
+ /runControllerCheck\s*\(/,
108
+ 'route rh_work verify through persisted Process Runtime instead of synchronous check execution',
109
+ );
99
110
  for (const adapter of [
100
111
  'src/cli/controller/work-mode.ts',
101
112
  'src/runtime/control-plane/facade/types.ts',
@@ -254,12 +265,7 @@ forbid(
254
265
  /buildSupervisorCommand|addCommand\(buildSupervisorCommand\(\)\)/,
255
266
  'the public root CLI must not expose the legacy Supervisor lifecycle',
256
267
  );
257
- forbid(
258
- 'src/cli/commands/controller.ts',
259
- /controller\/lifecycle|restart-coordinator|bluegreen-rollout|controllerRestartVerify|controllerFeatureVerify|command\.command\(['"](?:start|stop|status|restart|logs|rollout|rollback|restart-verify|feature-verify)['"]\)/,
260
- 'the public controller CLI must not expose component lifecycle, restart, blue-green rollout, rollback, or green-gate commands',
261
- );
262
- requireText('src/cli/commands/controller.ts', 'repositoryChangeVerify');
268
+ requireMissing('src/cli/commands/controller.ts');
263
269
  requireText('src/runtime/root/release-manifest.ts', "entrypoint must be forge-runtime");
264
270
  requireText('src/runtime/root/release-manifest.ts', 'databaseSchemaCompatibility');
265
271
  requireText('src/runtime/root/release-manifest.ts', 'workerProtocolVersion');
@@ -363,21 +369,11 @@ forbid(
363
369
  /\bcreateExecutionJob\b|\bfindExecutionJob\b/,
364
370
  'Portfolio definitions are planning records; Kernel-owned Portfolio execution is retired',
365
371
  );
366
- forbid(
367
- 'src/runtime/workflow/campaigns/engine.ts',
368
- /\bcreateExecutionJob\b|\bfindExecutionJob\b|\bgetExecutionJob\b|\bdispatchTask\b|\btriggerSupervisor\b/,
369
- 'Campaign Engine is migration-only and must not retain automatic Job dispatch, retry, or supervisor trigger code',
370
- );
371
372
  forbid(
372
373
  'src/cli/local-bridge/server.ts',
373
374
  /\bsubmitLocalBridgeJob\b|\bdispatchLocalBridgeJob\b|\basyncExecute\b/,
374
375
  'Local Bridge HTTP creation routes must return retirement handoffs without dormant Job submission or dispatch code',
375
376
  );
376
- forbid(
377
- 'src/cli/commands/controller.ts',
378
- /\bsubmitLocalBridgeJob\b|\bdispatchLocalBridgeJob\b/,
379
- 'Controller CLI launch must return an external-Controller handoff without dormant Local Bridge Job code',
380
- );
381
377
  forbid(
382
378
  'src/cli/mcp/repository-tools.ts',
383
379
  /\bsubmitLocalBridgeJob\b|\bexecuteLocalBridgeJob\b|\bwaitForRepositoryCommandHandoff\b/,
@@ -429,11 +425,6 @@ forbid(
429
425
  /\bretryAgentJob\b/,
430
426
  'Legacy MCP must not call Agent Run retry',
431
427
  );
432
- forbid(
433
- 'src/runtime/workflow/campaigns/engine.ts',
434
- /\bacceptTaskJob\b|\bstartTaskJob\b|\bretryAgentJob\b|\blaunchAgent\b/,
435
- 'Campaign Engine must not start or retry Kernel-managed Agent Runs',
436
- );
437
428
  forbid(
438
429
  'src/runtime/workflow/portfolio/engine.ts',
439
430
  /\bacceptTaskJob\b|\bstartTaskJob\b|\bretryAgentJob\b/,
@@ -571,6 +562,7 @@ for (const path of [
571
562
  'src/runtime/control-plane/global-scheduler/scheduler.ts',
572
563
  'src/runtime/control-plane/repo-actor/actor.ts',
573
564
  'src/runtime/workflow/schedules/engine.ts',
565
+ 'src/runtime/workflow/schedules/work-continuation.ts',
574
566
  'src/cli/mcp/transports/http.ts',
575
567
  ]) {
576
568
  forbid(path, /\b(?:spawnSync|execSync|execFileSync)\s*\(/, 'the non-blocking Gateway/Controller hot-path rule');
@@ -34,8 +34,9 @@ mkdir -p "$APP_DIR" "$TARGET_REPO"
34
34
  git -C "$TARGET_REPO" init -q
35
35
 
36
36
  cd "$APP_DIR"
37
- bun init -y >/dev/null
38
- bun add "$TARBALL_PATH" >/dev/null
37
+ printf '{"private":true,"name":"forge-tarball-smoke","version":"0.0.0"}
38
+ ' > package.json
39
+ npm install "$TARBALL_PATH" --omit=optional --ignore-scripts --no-audit --no-fund >/dev/null
39
40
 
40
41
  CLI="$APP_DIR/node_modules/.bin/forge"
41
42
  HOOK="$APP_DIR/node_modules/.bin/forge-hook"
@@ -724,8 +724,8 @@ helper_compat_dir="$(policy_get '.harness.helper_compat_dir' 'scripts')"
724
724
  helper_source="$(policy_get '.harness.helper_source' 'package')"
725
725
  context_map_file="$(policy_get '.context.map_file' '.ai/context/context-map.json')"
726
726
  brain_manifest_file="$(policy_get '.information_lifecycle.external_knowledge.manifest_file' '.ai/harness/brain-manifest.json')"
727
- handoff_file="$(policy_get '.harness.handoff_file' '.ai/harness/handoff/current.md')"
728
- resume_file="$(policy_get '.handoff_resume.resume_packet_file' '.ai/harness/handoff/resume.md')"
727
+ handoff_file="$(policy_get '.session.continuation_file' '.ai/harness/session/continuation.md')"
728
+ resume_file="$(policy_get '.session.resume_file' '.ai/harness/session/resume.md')"
729
729
  sprints_dir="$(policy_get '.sprints.dir' 'plans/sprints')"
730
730
  sprint_marker_file="$(policy_get '.sprints.active_marker_file' '.ai/harness/sprint/active-sprint')"
731
731
  legacy_sprints_dir="tasks/sprints"
@@ -200,8 +200,8 @@ latest_global_handoff() {
200
200
  find "$codex_home/handoffs" -maxdepth 1 -type f -name 'handoff-*.md' 2>/dev/null | sort | tail -1
201
201
  }
202
202
 
203
- resume_file="$(safe_repo_file "$(policy_get '.handoff_resume.resume_packet_file' '.ai/harness/handoff/resume.md')" '.ai/harness/handoff/resume.md' '.ai/harness/')"
204
- repo_handoff="$(safe_repo_file "$(policy_get '.harness.handoff_file' '.ai/harness/handoff/current.md')" '.ai/harness/handoff/current.md' '.ai/harness/')"
203
+ resume_file="$(safe_repo_file "$(policy_get '.session.resume_file' '.ai/harness/session/resume.md')" '.ai/harness/session/resume.md' '.ai/harness/')"
204
+ repo_handoff="$(safe_repo_file "$(policy_get '.session.continuation_file' '.ai/harness/session/continuation.md')" '.ai/harness/session/continuation.md' '.ai/harness/')"
205
205
  checks_file="$(safe_repo_file "$(policy_get '.harness.checks_file' '.ai/harness/checks/latest.json')" '.ai/harness/checks/latest.json' '.ai/harness/')"
206
206
  research_dir="$(safe_repo_file "$(policy_get '.tasks.research_dir' 'docs/researches')" 'docs/researches' 'docs/researches')"
207
207
  todo_file="$(safe_repo_file "$(policy_get '.tasks.todo_file' 'tasks/todos.md')" 'tasks/todos.md' 'tasks/')"
@@ -222,7 +222,7 @@ cat > "$resume_file" <<EOF_RESUME
222
222
 
223
223
  ## Resume Prompt
224
224
 
225
- You are starting a fresh Codex session for an existing long-running task. Do not rely on prior chat history or Codex auto-compact. First read the source artifacts listed below, then continue from the exact next step in the repo handoff.
225
+ You are starting a fresh Codex session for an existing long-running task. Do not rely on prior chat history or Codex auto-compact. First read the current user input and Canonical Runtime state when available, then source/evidence artifacts, and use the session continuation cache only to recover the exact next step.
226
226
 
227
227
  Current prompt files first:
228
228
  - If the current user message lists files under \`# Files mentioned by the user\`, references \`pasted-text.txt\`, or includes an explicit attachment/file path, read those current-input files before the repo recovery artifacts below.
@@ -243,7 +243,7 @@ Conditional first reads:
243
243
  - Global handoff: ${global_handoff:-(none)}
244
244
 
245
245
  Execution rules:
246
- - Treat filesystem artifacts as the source of truth.
246
+ - Treat Canonical Runtime lifecycle state as authoritative for migrated Requirement/Plan/Work state; treat Git source/evidence as authoritative in their own domains and session Markdown as rebuildable cache only.
247
247
  - Decide in the main agent whether to use subagents, parallel sidecars, sidecar \`codex exec --json\`, or a bounded main-thread trace for broad research/log scans based on context impact and callable tools; do not ask the user for spawn confirmation.
248
248
  - Keep deep research conclusions in \`${research_dir}/\`, not only in chat.
249
249
  - Do not run \`/compact\` as the primary recovery path.
@@ -251,7 +251,7 @@ Execution rules:
251
251
 
252
252
  ## Source Artifacts
253
253
 
254
- - Repo handoff: ${repo_handoff}
254
+ - Session continuation: ${repo_handoff}
255
255
  - Resume packet: ${resume_file}
256
256
  - Checks: ${checks_file}
257
257
  - Todo: ${todo_file}
@@ -87,7 +87,7 @@ fi
87
87
  mkdir -p .ai/hooks
88
88
  mkdir -p .ai/context
89
89
  mkdir -p .ai/harness/checks
90
- mkdir -p .ai/harness/handoff
90
+ mkdir -p .ai/harness/session .ai/harness/controller/packets .ai/harness/projections .ai/harness/transfers
91
91
  mkdir -p .ai/harness/failures
92
92
  mkdir -p .ai/harness/security
93
93
  mkdir -p .ai/harness/runs
@@ -201,8 +201,8 @@ DOCS_SPEC_EOF
201
201
  # - .ai/harness/checks/latest.json
202
202
  # - .ai/harness/events.jsonl
203
203
  # - .ai/harness/architecture/events.jsonl
204
- # - .ai/harness/handoff/current.md
205
- # - .ai/harness/handoff/resume.md
204
+ # - .ai/harness/session/continuation.md
205
+ # - .ai/harness/session/resume.md
206
206
  # - .ai/harness/failures/latest.jsonl
207
207
  # - .ai/harness/security/.gitkeep
208
208
  # - .ai/harness/worktrees/.gitkeep