@moretea-labs/forge 1.7.2 → 1.8.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 (900) hide show
  1. package/AGENTS.md +121 -62
  2. package/CHANGELOG.md +40 -0
  3. package/CLAUDE.md +57 -62
  4. package/CONTRIBUTING.md +3 -2
  5. package/README.md +2 -2
  6. package/SKILL.md +0 -1
  7. package/THIRD_PARTY_NOTICES.md +5 -2
  8. package/adapters/browser/index.ts +2 -0
  9. package/adapters/chatgpt/browser-delivery-host.ts +77 -0
  10. package/adapters/chatgpt/browser-delivery-runtime.ts +1256 -0
  11. package/adapters/chatgpt/controller-binding-store.ts +134 -0
  12. package/adapters/chatgpt/controller-round-host.ts +68 -0
  13. package/adapters/chatgpt/controller-round-settlement-store.ts +99 -0
  14. package/adapters/chatgpt/provider-delivery.ts +340 -0
  15. package/adapters/chatgpt/work-conversation-binding-store.ts +218 -0
  16. package/adapters/chatgpt/wsl-bridge-delivery-host.ts +63 -0
  17. package/adapters/computer/chatgpt-extension-target.ts +463 -0
  18. package/adapters/computer/chatgpt-target-router.ts +103 -0
  19. package/adapters/computer/chrome-extension/background.js +385 -0
  20. package/adapters/computer/chrome-extension/content.js +378 -0
  21. package/adapters/computer/chrome-extension/core.js +24 -0
  22. package/adapters/computer/chrome-extension/manifest.json +30 -0
  23. package/adapters/computer/desktop-operator-contract.ts +7 -0
  24. package/adapters/computer/desktop-operator-discovery.ts +181 -0
  25. package/adapters/computer/desktop-operator-negotiation.ts +174 -0
  26. package/adapters/computer/desktop-operator-provider.ts +312 -0
  27. package/adapters/computer/index.ts +1 -0
  28. package/adapters/computer/interaction-target-authority.ts +1068 -0
  29. package/adapters/controller-process/binding-store.ts +34 -0
  30. package/adapters/controller-process/controller-host.ts +26 -0
  31. package/adapters/mcp/access-mode.ts +132 -0
  32. package/adapters/mcp/audit.ts +32 -0
  33. package/adapters/mcp/auth.ts +406 -0
  34. package/adapters/mcp/instructions.ts +37 -0
  35. package/adapters/mcp/legacy-context.ts +18 -0
  36. package/adapters/mcp/multi-repository.ts +421 -0
  37. package/adapters/mcp/oauth.ts +464 -0
  38. package/adapters/mcp/paths.ts +143 -0
  39. package/adapters/mcp/policy.ts +232 -0
  40. package/adapters/mcp/proxy-env.ts +62 -0
  41. package/adapters/mcp/readiness-projection.ts +24 -0
  42. package/adapters/mcp/redaction.ts +21 -0
  43. package/adapters/mcp/repo.ts +24 -0
  44. package/adapters/mcp/runtime-gateway/artifact-adapter.ts +52 -0
  45. package/adapters/mcp/runtime-gateway/automation-receipt-adapter.ts +87 -0
  46. package/adapters/mcp/runtime-gateway/bounded-result-runtime.ts +62 -0
  47. package/adapters/mcp/runtime-gateway/cognition-settlement.ts +201 -0
  48. package/adapters/mcp/runtime-gateway/context-adapter.ts +1167 -0
  49. package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +91 -0
  50. package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +206 -0
  51. package/adapters/mcp/runtime-gateway/core-capability-adapter.ts +258 -0
  52. package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +130 -0
  53. package/adapters/mcp/runtime-gateway/engineering-tool-contract.ts +15 -0
  54. package/adapters/mcp/runtime-gateway/execution-control-adapter.ts +28 -0
  55. package/adapters/mcp/runtime-gateway/execution-tools.ts +173 -0
  56. package/adapters/mcp/runtime-gateway/filesystem-adapter.ts +38 -0
  57. package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +412 -0
  58. package/adapters/mcp/runtime-gateway/legacy-ios-tool-adapter.ts +105 -0
  59. package/adapters/mcp/runtime-gateway/maintenance-adapter.ts +44 -0
  60. package/adapters/mcp/runtime-gateway/model-adapter.ts +63 -0
  61. package/adapters/mcp/runtime-gateway/persisted-check-process.ts +3 -0
  62. package/adapters/mcp/runtime-gateway/plugin-adapter.ts +380 -0
  63. package/adapters/mcp/runtime-gateway/process-tools.ts +457 -0
  64. package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +88 -0
  65. package/adapters/mcp/runtime-gateway/recovery-adapter.ts +285 -0
  66. package/adapters/mcp/runtime-gateway/recovery-client-adapter.ts +70 -0
  67. package/adapters/mcp/runtime-gateway/recovery-tool-contract.ts +99 -0
  68. package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +79 -0
  69. package/adapters/mcp/runtime-gateway/result-adapter.ts +114 -0
  70. package/adapters/mcp/runtime-gateway/router.ts +242 -0
  71. package/adapters/mcp/runtime-gateway/routing-policy.ts +499 -0
  72. package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +1200 -0
  73. package/adapters/mcp/runtime-gateway/runtime-readiness-observation.ts +218 -0
  74. package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +574 -0
  75. package/adapters/mcp/runtime-gateway/runtime-tool-shared.ts +27 -0
  76. package/adapters/mcp/runtime-gateway/runtime-tools.ts +78 -0
  77. package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +187 -0
  78. package/adapters/mcp/runtime-gateway/shared-adapter.ts +45 -0
  79. package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +962 -0
  80. package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +136 -0
  81. package/adapters/mcp/runtime-gateway/work-adapter.ts +325 -0
  82. package/adapters/mcp/runtime-gateway/work-controller-operations.ts +257 -0
  83. package/adapters/mcp/runtime-gateway/work-detail-projection.ts +60 -0
  84. package/adapters/mcp/runtime-gateway/work-input-wire-migration.ts +246 -0
  85. package/adapters/mcp/runtime-gateway/work-learning-operations.ts +145 -0
  86. package/adapters/mcp/runtime-gateway/work-list-projection.ts +38 -0
  87. package/adapters/mcp/runtime-gateway/work-plan-operations.ts +382 -0
  88. package/adapters/mcp/runtime-gateway/work-repair-adapter.ts +308 -0
  89. package/adapters/mcp/runtime-gateway/work-requirement-operations.ts +148 -0
  90. package/adapters/mcp/runtime-gateway/work-semantic-operations.ts +263 -0
  91. package/adapters/mcp/runtime-gateway/work-validation-reconciler.ts +1 -0
  92. package/adapters/mcp/runtime-gateway/work-workflow-operations.ts +113 -0
  93. package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +156 -0
  94. package/adapters/mcp/server.ts +1092 -0
  95. package/adapters/mcp/setup.ts +789 -0
  96. package/adapters/mcp/tool-capability-cache.ts +87 -0
  97. package/adapters/mcp/tool-mapping/access-tools.ts +387 -0
  98. package/adapters/mcp/tool-mapping/legacy-tool-service.ts +5139 -0
  99. package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +145 -0
  100. package/adapters/mcp/tool-mapping/repository-tools.ts +1682 -0
  101. package/adapters/mcp/tool-mapping/tools.ts +9 -0
  102. package/adapters/mcp/tool-mapping/umbrella-tools.ts +117 -0
  103. package/adapters/mcp/toolset-names.ts +79 -0
  104. package/adapters/mcp/toolset-selection.ts +41 -0
  105. package/adapters/mcp/toolset.ts +337 -0
  106. package/adapters/mcp/transports/http-observation.ts +365 -0
  107. package/adapters/mcp/transports/http.ts +933 -0
  108. package/adapters/mcp/transports/oauth-http.ts +322 -0
  109. package/adapters/mcp/transports/session-registry.ts +519 -0
  110. package/adapters/mcp/transports/stdio.ts +8 -0
  111. package/adapters/mcp/tunnels/openai-secure-tunnel.ts +223 -0
  112. package/adapters/mcp/types.ts +41 -0
  113. package/assets/AGENTS.md +2 -16
  114. package/assets/CLAUDE.md +2 -16
  115. package/assets/hooks/AGENTS.md +3 -14
  116. package/assets/hooks/CLAUDE.md +3 -14
  117. package/assets/hooks/hook-input.sh +9 -2
  118. package/assets/hooks/lib/workflow-state.sh +28 -10
  119. package/assets/hooks/prompt-guard.sh +63 -37
  120. package/assets/hooks/security-sentinel.sh +2 -1
  121. package/assets/hooks/session-start-context.sh +7 -5
  122. package/assets/hooks/stop-orchestrator.sh +13 -3
  123. package/assets/initializer-question-pack.v4.json +11 -7
  124. package/assets/partials/05-workflow.partial.md +18 -73
  125. package/assets/partials/07-footer.partial.md +1 -1
  126. package/assets/partials-agents/02-operating-mode.partial.md +1 -2
  127. package/assets/partials-agents/04-task-protocol.partial.md +14 -59
  128. package/assets/partials-agents/06-quality-safety.partial.md +11 -16
  129. package/assets/partials-agents/08-deep-docs.partial.md +1 -2
  130. package/assets/plan-map.json +11 -11
  131. package/assets/plugin-registry.v1.json +11 -3
  132. package/assets/plugin-trust-policy.v1.json +6 -0
  133. package/assets/recovery/ForgeRecovery.ps1 +100 -0
  134. package/assets/recovery/forge-wsl-rescue +271 -0
  135. package/assets/reference-configs/agentic-development-flow.md +25 -0
  136. package/assets/reference-configs/development-protocol.md +11 -15
  137. package/assets/reference-configs/document-generation.md +1 -1
  138. package/assets/reference-configs/global-working-rules.md +28 -1
  139. package/assets/reference-configs/harness-overview.md +22 -112
  140. package/assets/reference-configs/hook-operations.md +1 -1
  141. package/assets/reference-configs/sprint-contracts.md +2 -2
  142. package/assets/skill-version.json +2 -2
  143. package/assets/templates/helpers/architecture-event.ts +3 -34
  144. package/assets/templates/helpers/architecture-queue.sh +61 -10
  145. package/assets/templates/helpers/archive-workflow.sh +90 -180
  146. package/assets/templates/helpers/capability-config.ts +8 -11
  147. package/assets/templates/helpers/capability-resolver.ts +37 -19
  148. package/assets/templates/helpers/capture-plan.sh +2 -2
  149. package/assets/templates/helpers/check-architecture-sync.sh +1 -9
  150. package/assets/templates/helpers/check-task-sync.sh +82 -11
  151. package/assets/templates/helpers/check-task-workflow.sh +1 -3
  152. package/assets/templates/helpers/context-contract-sync.sh +1 -12
  153. package/assets/templates/helpers/contract-worktree.sh +26 -24
  154. package/assets/templates/helpers/ensure-task-workflow.sh +6 -8
  155. package/assets/templates/helpers/inspect-project-state.ts +1 -1
  156. package/assets/templates/helpers/migrate-project-template.sh +1 -1
  157. package/assets/templates/helpers/migrate-workflow-docs.ts +53 -239
  158. package/assets/templates/helpers/new-plan.sh +2 -2
  159. package/assets/templates/helpers/plan-to-todo.sh +3 -31
  160. package/assets/templates/helpers/sprint-backlog.sh +1 -1
  161. package/assets/templates/helpers/switch-plan.sh +1 -1
  162. package/assets/templates/helpers/workflow-contract.ts +1 -0
  163. package/assets/workflow-contract.v1.json +63 -171
  164. package/assets/workflows/xiaohongshu/xiaohongshu.collect-metrics.v1.draft.json +118 -0
  165. package/assets/workflows/xiaohongshu/xiaohongshu.publish-image-note.v1.draft.json +316 -0
  166. package/assets/workflows/xiaohongshu/xiaohongshu.publish-long-text.v1.draft.json +324 -0
  167. package/docs/architecture/CURRENT.md +233 -28
  168. package/docs/architecture/EVOLUTION.md +13 -0
  169. package/docs/architecture/decisions/20260801-controller-home-sqlite-state.md +2 -1
  170. package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +14 -5
  171. package/docs/architecture/decisions/20260823-immediate-controller-relay.md +6 -3
  172. package/docs/architecture/decisions/20260831-independent-windows-wsl-host-rescue.md +59 -0
  173. package/docs/architecture/decisions/20260904-ios-device-migration-baseline.md +120 -0
  174. package/docs/architecture/decisions/20260904-repository-runtime-data-boundary.md +42 -0
  175. package/docs/architecture/decisions/20260907-assistant-learning-loop.md +37 -0
  176. package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +311 -0
  177. package/docs/architecture/decisions/20260907-maintenance-diagnosis-bounded-read.md +39 -0
  178. package/docs/architecture/decisions/20260916-workflow-supervisor-authority.md +249 -0
  179. package/docs/architecture/decisions/20260917-cognitive-memory-foundation.md +82 -0
  180. package/docs/architecture/decisions/20260918-stable-candidate-release-lifecycle.md +221 -0
  181. package/docs/architecture/decisions/20260919-autonomous-work-liveness.md +62 -0
  182. package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +72 -0
  183. package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +237 -0
  184. package/docs/architecture/decisions/20261005-forge-v3-desktop-client-boundary.md +77 -0
  185. package/docs/architecture/domains/verification.md +8 -0
  186. package/docs/architecture/domains/workflow-engine.md +7 -1
  187. package/docs/architecture/index.md +3 -3
  188. package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +19 -8
  189. package/docs/architecture/requests/2026-09-04-computer-plugin-workflow-taxonomy.md +124 -0
  190. package/docs/forge-chatgpt-mcp-setup.md +5 -3
  191. package/docs/forge-plugin-management.md +20 -4
  192. package/docs/forge-runtime-self-healing-loop.md +2 -0
  193. package/docs/operations/benchmark-cross-version-freeze.md +38 -0
  194. package/docs/operations/controller-browser-plugin.md +3 -1
  195. package/docs/operations/controller-performance-and-502.md +17 -0
  196. package/docs/operations/controller-reliability-runbook.md +2 -2
  197. package/docs/operations/features.md +1 -1
  198. package/docs/operations/features.zh-CN.md +1 -1
  199. package/docs/operations/homebrew.md +2 -2
  200. package/docs/operations/mcp-tool-exposure.md +2 -0
  201. package/docs/operations/platform-support.md +16 -8
  202. package/docs/operations/platform-support.zh-CN.md +2 -2
  203. package/docs/operations/releasing.md +2 -0
  204. package/docs/operations/standalone-disaster-recovery.md +38 -5
  205. package/docs/operations/uu-remote-rescue.md +41 -0
  206. package/docs/operations/windows-wsl-host-rescue.md +133 -0
  207. package/docs/public-usage-guide.md +1 -1
  208. package/docs/public-usage-guide.zh-CN.md +1 -1
  209. package/docs/tutorials/01-install-and-start.md +1 -1
  210. package/docs/tutorials/01-install-and-start.zh-CN.md +1 -1
  211. package/docs/tutorials/02-connect-chatgpt.md +4 -4
  212. package/docs/tutorials/02-connect-chatgpt.zh-CN.md +4 -4
  213. package/docs/wiki/Implementation.md +1 -1
  214. package/package.json +46 -26
  215. package/packages/kernel/cognition/api/index.ts +6 -0
  216. package/packages/kernel/cognition/application/activation-service.ts +451 -0
  217. package/packages/kernel/cognition/application/consolidation-service.ts +185 -0
  218. package/packages/kernel/cognition/application/legacy-experience-adapter.ts +38 -0
  219. package/packages/kernel/cognition/application/memory-service.ts +64 -0
  220. package/packages/kernel/cognition/domain/learning.ts +106 -0
  221. package/packages/kernel/cognition/domain/memory.ts +254 -0
  222. package/packages/kernel/controller/api/index.ts +3 -0
  223. package/packages/kernel/controller/application/continuation-service.ts +281 -0
  224. package/packages/kernel/controller/application/controller-round-service.ts +41 -0
  225. package/packages/kernel/controller/application/controller-service.ts +30 -0
  226. package/packages/kernel/controller/domain/controller-round-transition-policy.ts +529 -0
  227. package/packages/kernel/controller/domain/controller-round.ts +110 -0
  228. package/packages/kernel/controller/domain/execution-quality.ts +135 -0
  229. package/packages/kernel/controller/domain/types.ts +56 -0
  230. package/packages/kernel/controller/index.ts +1 -0
  231. package/packages/kernel/controller/infrastructure/controller-binding-store.ts +84 -0
  232. package/packages/kernel/controller/infrastructure/controller-round-store.ts +1970 -0
  233. package/packages/kernel/controller/infrastructure/controller-session-store.ts +804 -0
  234. package/packages/kernel/controller/ports/controller-host.ts +18 -0
  235. package/packages/kernel/goal/api/index.ts +1 -0
  236. package/packages/kernel/goal/domain/types.ts +40 -0
  237. package/packages/kernel/goal/index.ts +1 -0
  238. package/packages/kernel/identity/api/index.ts +15 -0
  239. package/packages/kernel/identity/application/identity-service.ts +67 -0
  240. package/packages/kernel/identity/domain/activity-projection.ts +43 -0
  241. package/packages/kernel/identity/domain/capability-broker.ts +60 -0
  242. package/packages/kernel/identity/domain/grant.ts +72 -0
  243. package/packages/kernel/identity/domain/owned-resource.ts +116 -0
  244. package/packages/kernel/identity/domain/scope.ts +63 -0
  245. package/packages/kernel/identity/domain/semantic-sync.ts +81 -0
  246. package/packages/kernel/identity/domain/types.ts +44 -0
  247. package/packages/kernel/identity/domain/user-request.ts +93 -0
  248. package/packages/kernel/identity/domain/workspace.ts +56 -0
  249. package/packages/kernel/identity/index.ts +1 -0
  250. package/packages/kernel/identity/infrastructure/activity-projection-store.ts +77 -0
  251. package/packages/kernel/identity/infrastructure/capability-broker.ts +81 -0
  252. package/packages/kernel/identity/infrastructure/grant-store.ts +284 -0
  253. package/packages/kernel/identity/infrastructure/identity-store.ts +75 -0
  254. package/packages/kernel/identity/infrastructure/owned-resource-store.ts +259 -0
  255. package/packages/kernel/identity/infrastructure/user-request-store.ts +182 -0
  256. package/packages/kernel/memory/api/index.ts +5 -0
  257. package/packages/kernel/memory/application/experience-service.ts +118 -0
  258. package/packages/kernel/memory/application/outcome-service.ts +77 -0
  259. package/packages/kernel/memory/domain/experience.ts +103 -0
  260. package/packages/kernel/memory/domain/operational-prior.ts +92 -0
  261. package/packages/kernel/memory/index.ts +1 -0
  262. package/packages/kernel/scheduler/api/index.ts +4 -0
  263. package/packages/kernel/scheduler/application/eligibility.ts +252 -0
  264. package/packages/kernel/scheduler/application/schedule-service.ts +27 -0
  265. package/packages/kernel/scheduler/application/settlement.ts +182 -0
  266. package/packages/kernel/scheduler/domain/schedule.ts +236 -0
  267. package/packages/kernel/scheduler/index.ts +1 -0
  268. package/packages/kernel/scheduler/infrastructure/schedule-store.ts +805 -0
  269. package/packages/kernel/work/api/index.ts +16 -0
  270. package/packages/kernel/work/application/work-service.ts +123 -0
  271. package/packages/kernel/work/domain/check-receipt.ts +43 -0
  272. package/packages/kernel/work/domain/context-closure-receipt.ts +32 -0
  273. package/packages/kernel/work/domain/current-task-lineage.ts +104 -0
  274. package/packages/kernel/work/domain/engineering-contracts.ts +157 -0
  275. package/packages/kernel/work/domain/engineering-design.ts +286 -0
  276. package/packages/kernel/work/domain/engineering-profile.ts +238 -0
  277. package/packages/kernel/work/domain/evaluation-promotion-receipt.ts +186 -0
  278. package/packages/kernel/work/domain/execution-concurrency.ts +247 -0
  279. package/packages/kernel/work/domain/execution-snapshot.ts +2 -0
  280. package/packages/kernel/work/domain/implementation-review.ts +193 -0
  281. package/packages/kernel/work/domain/objective-graph.ts +119 -0
  282. package/packages/kernel/work/domain/project-engineering-contract.ts +224 -0
  283. package/packages/kernel/work/domain/repository-completion-receipt.ts +73 -0
  284. package/{src/runtime/control-plane/facade/work-state-machine.ts → packages/kernel/work/domain/state-machine.ts} +37 -66
  285. package/packages/kernel/work/domain/types.ts +534 -0
  286. package/packages/kernel/work/index.ts +1 -0
  287. package/packages/kernel/work/infrastructure/work-contract-store.ts +1967 -0
  288. package/packages/kernel/work/ports/work-contract-store.ts +21 -0
  289. package/packages/plugin-runtime/browser/index.ts +3 -0
  290. package/packages/plugin-runtime/browser/provider-registry.ts +110 -0
  291. package/packages/plugin-runtime/browser/runtime-contract.ts +150 -0
  292. package/packages/plugin-runtime/browser/session-authority.ts +62 -0
  293. package/packages/plugin-runtime/computer/chatgpt-identity.ts +24 -0
  294. package/packages/plugin-runtime/computer/conversation-target.ts +143 -0
  295. package/packages/plugin-runtime/computer/index.ts +8 -0
  296. package/packages/plugin-runtime/computer/provider-error.ts +26 -0
  297. package/packages/plugin-runtime/computer/provider-registration.ts +52 -0
  298. package/packages/plugin-runtime/computer/provider-registry.ts +63 -0
  299. package/packages/plugin-runtime/computer/provider.ts +19 -0
  300. package/packages/plugin-runtime/computer/target-authority.ts +215 -0
  301. package/packages/plugin-runtime/computer/target-persistence.ts +54 -0
  302. package/packages/plugin-runtime/external/index.ts +1 -0
  303. package/packages/plugin-runtime/external/unix-jsonl-transport.ts +581 -0
  304. package/packages/plugin-runtime/index.ts +3 -0
  305. package/packages/protocols/browser/index.ts +1 -0
  306. package/packages/protocols/browser/session.ts +98 -0
  307. package/packages/protocols/computer/contract.ts +225 -0
  308. package/packages/protocols/computer/index.ts +1 -0
  309. package/packages/protocols/failure/contract.ts +158 -0
  310. package/packages/protocols/failure/index.ts +1 -0
  311. package/packages/protocols/handoff/index.ts +1 -0
  312. package/packages/protocols/handoff/status.ts +22 -0
  313. package/packages/protocols/mcp/execution-context.ts +11 -0
  314. package/packages/protocols/mcp/index.ts +2 -0
  315. package/packages/protocols/mcp/tool-contract.ts +42 -0
  316. package/packages/workflow-runtime/api/index.ts +2 -0
  317. package/packages/workflow-runtime/application/interpreter.ts +342 -0
  318. package/packages/workflow-runtime/domain/workflow-asset.ts +223 -0
  319. package/packages/workflow-runtime/index.ts +1 -0
  320. package/scripts/activate-source-baseline.ts +7 -9
  321. package/scripts/assemble-template.ts +1 -1
  322. package/scripts/bootstrap-runtime-maintenance-recovery.sh +4 -1
  323. package/scripts/canary-chatgpt-provider-delivery.ts +97 -0
  324. package/scripts/canary-controller-semantic-wait.ts +183 -0
  325. package/scripts/canary-global-hook.sh +2 -2
  326. package/scripts/check-mcp-compatibility.ts +85 -7
  327. package/scripts/check-platform-support.mjs +28 -2
  328. package/scripts/check-public-docs.sh +1 -1
  329. package/scripts/check-repository-hygiene.mjs +92 -0
  330. package/scripts/check-runtime-architecture.mjs +1643 -127
  331. package/scripts/check-source-duplication.mjs +9 -1
  332. package/scripts/controller-ngrok-rotation.sh +5 -4
  333. package/scripts/create-project-dirs.sh +10 -74
  334. package/scripts/forge-local-recovery-helper.mjs +282 -0
  335. package/scripts/forge-uu-remote-rescue-helper.d.mts +31 -0
  336. package/scripts/forge-uu-remote-rescue-helper.mjs +409 -0
  337. package/scripts/forge-windows-host-recovery-helper.mjs +136 -0
  338. package/scripts/hook-shim.sh +2 -2
  339. package/scripts/init-project.sh +12 -70
  340. package/scripts/install-desktop-operator-registration.ts +4 -2
  341. package/scripts/install-independent-windows-wsl-recovery.ts +125 -0
  342. package/scripts/install-standalone-recovery.ts +122 -10
  343. package/scripts/install-uu-remote-rescue-registration.ts +74 -0
  344. package/scripts/install-windows-host-recovery-registration.ts +22 -0
  345. package/scripts/lib/controller-home-env.sh +6 -3
  346. package/scripts/lib/project-init-lib.sh +42 -582
  347. package/scripts/migrate-chatgpt-automation-schedules.ts +2 -2
  348. package/scripts/migrate-windows-wsl-controller-home.ts +306 -0
  349. package/scripts/open-source-audit-allowlist.txt +11 -1
  350. package/scripts/portability-bindings.mjs +70 -0
  351. package/scripts/run-bounded-command.mjs +60 -0
  352. package/scripts/run-bun-test-file.ts +22 -6
  353. package/scripts/run-governed-gate.ts +4 -2
  354. package/scripts/run-mobile-monitor-bridge.ts +0 -1
  355. package/scripts/smoke-control-plane-failure-domain.ts +94 -0
  356. package/scripts/smoke-mcp-http-runtime.ts +6 -1
  357. package/scripts/smoke-runtime-recovery.ts +13 -11
  358. package/scripts/smoke-schedule-engine.ts +24 -16
  359. package/scripts/smoke-unattended-transport-recovery.ts +223 -0
  360. package/scripts/smoke-user-request-continuation-restart.ts +232 -0
  361. package/scripts/smoke-workflow-supervisor-chrome-adapter.ts +92 -0
  362. package/scripts/smoke-workflow-supervisor-process-restart.ts +276 -0
  363. package/scripts/smoke-workflow-supervisor-restart-recovery.ts +150 -0
  364. package/scripts/smoke-workflow-supervisor.ts +103 -0
  365. package/scripts/test-governance.ts +51 -2
  366. package/scripts/verify-forge-runtime.sh +2 -1
  367. package/src/cli/agent-jobs/executor-health.ts +11 -34
  368. package/src/cli/agent-jobs/integration.ts +18 -49
  369. package/src/cli/agent-jobs/job-manager.ts +17 -4
  370. package/src/cli/chatgpt-browser/bind-server.ts +2 -1
  371. package/src/cli/chatgpt-browser/binding.ts +20 -10
  372. package/src/cli/chatgpt-browser/bridge-extension.ts +75 -0
  373. package/src/cli/chatgpt-browser/bridge-provider.ts +376 -11
  374. package/src/cli/chatgpt-browser/engine.ts +10 -11
  375. package/src/cli/chatgpt-browser/native-provider.ts +24 -83
  376. package/src/cli/chatgpt-browser/oracle-provider.ts +5 -3
  377. package/src/cli/chatgpt-browser/types.ts +1 -0
  378. package/src/cli/commands/bootstrap-control.ts +334 -0
  379. package/src/cli/commands/brain-assistant.ts +52 -0
  380. package/src/cli/commands/brain.ts +191 -40
  381. package/src/cli/commands/chatgpt.ts +32 -67
  382. package/src/cli/commands/computer.ts +437 -0
  383. package/src/cli/commands/doctor.ts +18 -1
  384. package/src/cli/commands/init-hook.ts +71 -61
  385. package/src/cli/commands/init.ts +3 -1
  386. package/src/cli/commands/mcp.ts +16 -10
  387. package/src/cli/commands/plugin.ts +38 -12
  388. package/src/cli/commands/recovery.ts +507 -80
  389. package/src/cli/commands/runtime.ts +12 -7
  390. package/src/cli/commands/setup-profile.ts +97 -39
  391. package/src/cli/commands/status.ts +2 -1
  392. package/src/cli/controller/check-runner.ts +500 -100
  393. package/src/cli/controller/completion-backlog.ts +3 -3
  394. package/src/cli/controller/completion-orchestrator.ts +4 -43
  395. package/src/cli/controller/completion-target.ts +3 -72
  396. package/src/cli/controller/context/source-materializer.ts +81 -100
  397. package/src/cli/controller/context/types.ts +7 -1
  398. package/src/cli/controller/context-pack.ts +28 -6
  399. package/src/cli/controller/execution-completion.ts +4 -7
  400. package/src/cli/controller/execution-policy.ts +36 -153
  401. package/src/cli/controller/governance.ts +2 -3
  402. package/src/cli/controller/issue-store.ts +4 -99
  403. package/src/cli/controller/launch-agents.ts +59 -18
  404. package/src/cli/controller/operational-plan.ts +24 -51
  405. package/src/cli/controller/runtime-config.ts +5 -1
  406. package/src/cli/controller/stuck-state-migration.ts +2 -3
  407. package/src/cli/controller/systemd-user.ts +148 -0
  408. package/src/cli/controller/types.ts +10 -70
  409. package/src/cli/controller/worklog.ts +67 -13
  410. package/src/cli/editing/edit-operation-contract.ts +92 -0
  411. package/src/cli/editing/edit-session.ts +290 -20
  412. package/src/cli/github/plugin.ts +17 -12
  413. package/src/cli/hook/route-registry.ts +3 -5
  414. package/src/cli/hook/runtime.ts +49 -3
  415. package/src/cli/index.ts +3 -0
  416. package/src/cli/local-bridge/connector-freshness.ts +2 -2
  417. package/src/cli/local-bridge/console-automations.ts +20 -15
  418. package/src/cli/local-bridge/console-view-models.ts +3 -12
  419. package/src/cli/local-bridge/facade-api.ts +105 -205
  420. package/src/cli/local-bridge/job-store.ts +1 -1
  421. package/src/cli/local-bridge/server.ts +48 -174
  422. package/src/cli/local-bridge/types.ts +0 -1
  423. package/src/cli/mcp/access-mode.ts +2 -132
  424. package/src/cli/mcp/access-tools.ts +2 -387
  425. package/src/cli/mcp/audit.ts +2 -32
  426. package/src/cli/mcp/auth.ts +2 -404
  427. package/src/cli/mcp/instructions.ts +2 -34
  428. package/src/cli/mcp/legacy-context.ts +2 -16
  429. package/src/cli/mcp/legacy-tool-service.ts +2 -5308
  430. package/src/cli/mcp/multi-repository.ts +2 -436
  431. package/src/cli/mcp/oauth-client-retirement.ts +74 -0
  432. package/src/cli/mcp/oauth.ts +2 -375
  433. package/src/cli/mcp/openai-secure-tunnel.ts +2 -0
  434. package/src/cli/mcp/paths.ts +2 -140
  435. package/src/cli/mcp/policy.ts +2 -232
  436. package/src/cli/mcp/post-finalize-work-attribution.ts +2 -150
  437. package/src/cli/mcp/proxy-env.ts +2 -62
  438. package/src/cli/mcp/readiness-projection.ts +2 -24
  439. package/src/cli/mcp/redaction.ts +2 -21
  440. package/src/cli/mcp/repo.ts +2 -24
  441. package/src/cli/mcp/repository-tools.ts +2 -1613
  442. package/src/cli/mcp/server.ts +2 -951
  443. package/src/cli/mcp/setup.ts +2 -737
  444. package/src/cli/mcp/tool-capability-cache.ts +2 -87
  445. package/src/cli/mcp/tool-contract.ts +2 -14
  446. package/src/cli/mcp/tools.ts +2 -9
  447. package/src/cli/mcp/toolset-names.ts +2 -70
  448. package/src/cli/mcp/toolset-selection.ts +2 -41
  449. package/src/cli/mcp/toolset.ts +2 -336
  450. package/src/cli/mcp/transports/AGENTS.md +1 -10
  451. package/src/cli/mcp/transports/CLAUDE.md +1 -10
  452. package/src/cli/mcp/transports/http.ts +2 -1414
  453. package/src/cli/mcp/transports/session-registry.ts +2 -490
  454. package/src/cli/mcp/transports/stdio.ts +2 -8
  455. package/src/cli/mcp/types.ts +2 -41
  456. package/src/cli/mcp/umbrella-tools.ts +2 -117
  457. package/src/cli/repositories/command-executor.ts +91 -39
  458. package/src/cli/repositories/command-scope.ts +139 -4
  459. package/src/cli/repositories/controller-home.ts +167 -1
  460. package/src/cli/repositories/ephemeral-workspace.ts +20 -30
  461. package/src/cli/repositories/git-command-executor.ts +2 -2
  462. package/src/cli/repositories/identity.ts +13 -0
  463. package/src/cli/repositories/registry.ts +145 -60
  464. package/src/cli/repositories/repository-snapshot.ts +53 -7
  465. package/src/cli/repositories/runtime-storage.ts +27 -2
  466. package/src/cli/repositories/safe-patch.ts +34 -38
  467. package/src/cli/repositories/selected-path-actions.ts +22 -2
  468. package/src/cli/repositories/structured-git.ts +167 -27
  469. package/src/cli/repository/session-cache.ts +92 -6
  470. package/src/cli/runtime/helper-runner.ts +7 -0
  471. package/src/cli/runtime-invocation.ts +8 -1
  472. package/src/cli/tools/codegraph.ts +44 -25
  473. package/src/core/adoption/manifest-templates.ts +1 -1
  474. package/src/core/adoption/plan.ts +3 -26
  475. package/src/core/adoption/workflow-contract-plan.ts +17 -9
  476. package/src/effects/process-runner.ts +8 -14
  477. package/src/runtime/context/assistant-context.ts +167 -0
  478. package/src/runtime/context/assistant-work-context.ts +209 -0
  479. package/src/runtime/context/automatic-learning.ts +565 -0
  480. package/src/runtime/context/codegraph-cache-boundary.ts +255 -0
  481. package/src/runtime/context/codegraph-read-provider.ts +55 -22
  482. package/src/runtime/context/codegraph-sidecar.cjs +8 -1
  483. package/src/runtime/context/cognitive-attention.ts +173 -0
  484. package/src/runtime/context/cognitive-skill-canary.ts +158 -0
  485. package/src/runtime/context/context-closure.ts +305 -0
  486. package/src/runtime/context/context-pack-process.ts +103 -0
  487. package/src/runtime/context/context-plane.ts +203 -0
  488. package/src/runtime/context/direct-controller-learning.ts +298 -0
  489. package/src/runtime/context/project-engineering-contract.ts +60 -0
  490. package/src/runtime/context/semantic-navigation-contract.ts +9 -0
  491. package/src/runtime/context/semantic-navigation.ts +6 -34
  492. package/src/runtime/context/typescript-navigation-process.ts +145 -0
  493. package/src/runtime/context/typescript-navigation.ts +89 -3
  494. package/src/runtime/control-plane/bootstrap/capability-provider.ts +74 -0
  495. package/src/runtime/control-plane/bootstrap/control-api.ts +57 -0
  496. package/src/runtime/control-plane/bootstrap/index.ts +5 -0
  497. package/src/runtime/control-plane/bootstrap/state-machine.ts +141 -0
  498. package/src/runtime/control-plane/bootstrap/store.ts +21 -0
  499. package/src/runtime/control-plane/bootstrap/types.ts +87 -0
  500. package/src/runtime/control-plane/cleanup-artifact-retention.ts +531 -0
  501. package/src/runtime/control-plane/codegraph-cache-retention.ts +164 -0
  502. package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +282 -0
  503. package/src/runtime/control-plane/execution/controller-authority-recovery.ts +380 -0
  504. package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +113 -16
  505. package/src/runtime/control-plane/execution/execution-identity.ts +23 -3
  506. package/src/runtime/control-plane/execution/implementation-review-content.ts +95 -0
  507. package/src/runtime/control-plane/execution/repository-work-attribution.ts +7 -30
  508. package/src/runtime/control-plane/execution/retained-work-resume.ts +439 -102
  509. package/src/runtime/control-plane/execution/session-store.ts +31 -1
  510. package/src/runtime/control-plane/execution/validation.ts +34 -11
  511. package/src/runtime/control-plane/execution/work-authority-reconciler.ts +87 -0
  512. package/src/runtime/control-plane/execution/work-check-evidence.ts +137 -0
  513. package/src/runtime/control-plane/execution/work-completion-authority.ts +31 -44
  514. package/src/runtime/control-plane/execution/work-delivery-service.ts +497 -0
  515. package/src/runtime/control-plane/execution/work-evidence-policy.ts +46 -53
  516. package/src/runtime/control-plane/execution/work-execution-support.ts +85 -164
  517. package/src/runtime/control-plane/execution/work-handle-authority.ts +349 -73
  518. package/src/runtime/control-plane/execution/work-handle-store.ts +55 -2
  519. package/src/runtime/control-plane/execution/work-head-settlement.ts +108 -0
  520. package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +173 -28
  521. package/src/runtime/control-plane/execution/work-operation-service.ts +92 -40
  522. package/src/runtime/control-plane/execution/work-preparation-service.ts +145 -269
  523. package/src/runtime/control-plane/execution/work-remote-delivery.ts +2 -3
  524. package/src/runtime/control-plane/execution/work-revision-diff.ts +39 -0
  525. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +543 -225
  526. package/src/runtime/control-plane/execution/work-validation-reconciler.ts +59 -45
  527. package/src/runtime/control-plane/execution/work-verification-context.ts +1 -1
  528. package/src/runtime/control-plane/execution/work-verification-service.ts +662 -52
  529. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +205 -16
  530. package/src/runtime/control-plane/facade/capability-registry.ts +380 -44
  531. package/src/runtime/control-plane/facade/check-normalization.ts +3 -9
  532. package/src/runtime/control-plane/facade/codex-delegation.ts +10 -11
  533. package/src/runtime/control-plane/facade/controller-connection.ts +135 -0
  534. package/src/runtime/control-plane/facade/controller-session-store.ts +2 -488
  535. package/src/runtime/control-plane/facade/goal-workloop-access.ts +6 -22
  536. package/src/runtime/control-plane/facade/goal-workloop.ts +565 -1202
  537. package/src/runtime/control-plane/facade/handoff-inbox-application.ts +145 -0
  538. package/src/runtime/control-plane/facade/handoff-inbox-store.ts +266 -52
  539. package/src/runtime/control-plane/facade/index.ts +4 -3
  540. package/src/runtime/control-plane/facade/operation-digest.ts +34 -73
  541. package/src/runtime/control-plane/facade/plan-contract-store.ts +671 -245
  542. package/src/runtime/control-plane/facade/policy-gate.ts +0 -23
  543. package/src/runtime/control-plane/facade/repository-work-admission.ts +31 -23
  544. package/src/runtime/control-plane/facade/requirement-authority.ts +121 -0
  545. package/src/runtime/control-plane/facade/requirement-board.ts +9 -4
  546. package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +85 -0
  547. package/src/runtime/control-plane/facade/self-healing-loop.ts +18 -53
  548. package/src/runtime/control-plane/facade/semantic-admission.ts +8 -16
  549. package/src/runtime/control-plane/facade/suggested-actions.ts +15 -15
  550. package/src/runtime/control-plane/facade/types.ts +218 -620
  551. package/src/runtime/control-plane/facade/work-continuation.ts +8 -8
  552. package/src/runtime/control-plane/facade/work-contract-store.ts +2 -1043
  553. package/src/runtime/control-plane/generated-cache-retention.ts +336 -19
  554. package/src/runtime/control-plane/global-scheduler/autonomous-continuation.ts +248 -0
  555. package/src/runtime/control-plane/global-scheduler/durable-admission.ts +13 -2
  556. package/src/runtime/control-plane/global-scheduler/maintenance.ts +274 -84
  557. package/src/runtime/control-plane/global-scheduler/periodic-cleanup-entry.ts +55 -0
  558. package/src/runtime/control-plane/global-scheduler/periodic-cleanup-process.ts +98 -0
  559. package/src/runtime/control-plane/global-scheduler/reconciliation.ts +3 -2
  560. package/src/runtime/control-plane/global-scheduler/scheduler-worker-entry.ts +10 -0
  561. package/src/runtime/control-plane/global-scheduler/scheduler.ts +227 -109
  562. package/src/runtime/control-plane/global-scheduler/wake-signal.ts +42 -2
  563. package/src/runtime/control-plane/global-scheduler/worker-launch.ts +18 -6
  564. package/src/runtime/control-plane/governance/access-policy.ts +19 -2
  565. package/src/runtime/control-plane/governance/authorization.ts +20 -3
  566. package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +160 -0
  567. package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +2 -177
  568. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +139 -670
  569. package/src/runtime/control-plane/launcher/local-conversation-controller.ts +238 -0
  570. package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +25 -6
  571. package/src/runtime/control-plane/launcher/thin-launcher.ts +96 -194
  572. package/src/runtime/control-plane/lifecycle-retention-metrics.ts +60 -0
  573. package/src/runtime/control-plane/persistence/cognition-store.ts +820 -0
  574. package/src/runtime/control-plane/persistence/experience-store.ts +302 -0
  575. package/src/runtime/control-plane/persistence/operational-prior-store.ts +348 -0
  576. package/src/runtime/control-plane/persistence/requirement-store.ts +230 -80
  577. package/src/runtime/control-plane/persistence/sqlite-store.ts +654 -78
  578. package/src/runtime/control-plane/persistence/workflow-content-store.ts +98 -0
  579. package/src/runtime/control-plane/persistence/workflow-registry-store.ts +186 -0
  580. package/src/runtime/control-plane/persistence/workflow-run-store.ts +123 -0
  581. package/src/runtime/control-plane/release-retention.ts +154 -26
  582. package/src/runtime/control-plane/repository-namespace-retention.ts +208 -0
  583. package/src/runtime/control-plane/runtime-cleanup.ts +844 -38
  584. package/src/runtime/control-plane/runtime-generation.ts +6 -0
  585. package/src/runtime/control-plane/workspace/project-onboarding.ts +80 -0
  586. package/src/runtime/control-plane/workspace/semantic-sync-service.ts +479 -0
  587. package/src/runtime/control-plane/workspace/workspace-store.ts +249 -0
  588. package/src/runtime/diagnostics/incident-repair.ts +573 -0
  589. package/src/runtime/diagnostics/mcp-timing.ts +239 -6
  590. package/src/runtime/diagnostics/performance.ts +6 -14
  591. package/src/runtime/diagnostics/read-only-tool.ts +1 -1
  592. package/src/runtime/evidence/artifact-store.ts +216 -35
  593. package/src/runtime/evidence/evidence-store.ts +112 -8
  594. package/src/runtime/evidence/operational-shadow.ts +38 -0
  595. package/src/runtime/evidence/output-handle-index.ts +225 -0
  596. package/src/runtime/evidence/process-check-receipt.ts +5 -43
  597. package/src/runtime/evidence/result-store.ts +158 -44
  598. package/src/runtime/evidence/sensitive-output.ts +4 -4
  599. package/src/runtime/execution/jobs/receipt-recovery.ts +1 -1
  600. package/src/runtime/execution/jobs/store.ts +124 -6
  601. package/src/runtime/execution/managed-workspace.ts +112 -5
  602. package/src/runtime/execution/process-runtime/canary.ts +19 -5
  603. package/src/runtime/execution/process-runtime/check-classification.ts +48 -0
  604. package/src/runtime/execution/process-runtime/check-facade.ts +24 -10
  605. package/src/runtime/execution/process-runtime/check-receipt.ts +1 -1
  606. package/src/runtime/execution/process-runtime/check-result-retention.ts +132 -0
  607. package/src/runtime/execution/process-runtime/check-result.ts +177 -2
  608. package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +58 -9
  609. package/src/runtime/execution/process-runtime/check-storage.ts +187 -0
  610. package/src/runtime/execution/process-runtime/command-facade.ts +117 -114
  611. package/src/runtime/execution/process-runtime/gc.ts +15 -2
  612. package/src/runtime/execution/process-runtime/handle-index.ts +176 -0
  613. package/src/runtime/execution/process-runtime/host-command-lane.ts +139 -0
  614. package/src/runtime/execution/process-runtime/index.ts +4 -0
  615. package/src/runtime/execution/process-runtime/interactive-admission.ts +2 -1
  616. package/src/runtime/execution/process-runtime/lightweight-managed.ts +283 -73
  617. package/src/runtime/execution/process-runtime/persisted-check.ts +130 -23
  618. package/src/runtime/execution/process-runtime/process-runner-entry.ts +47 -5
  619. package/src/runtime/execution/process-runtime/process-scope.ts +160 -0
  620. package/src/runtime/execution/process-runtime/resource-claims.ts +125 -64
  621. package/src/runtime/execution/process-runtime/runtime.ts +167 -17
  622. package/src/runtime/execution/process-runtime/store.ts +30 -2
  623. package/src/runtime/execution/process-runtime/types.ts +27 -0
  624. package/src/runtime/execution/workers/executor.ts +18 -19
  625. package/src/runtime/execution/workers/worker-entry.ts +1 -1
  626. package/src/runtime/gateway/mcp/execution-tools.ts +2 -207
  627. package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +2 -61
  628. package/src/runtime/gateway/mcp/persisted-check-process.ts +2 -3
  629. package/src/runtime/gateway/mcp/process-tools.ts +2 -289
  630. package/src/runtime/gateway/mcp/router.ts +2 -1125
  631. package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +2 -565
  632. package/src/runtime/gateway/mcp/runtime-tools.ts +2 -6655
  633. package/src/runtime/gateway/mcp/work-validation-reconciler.ts +2 -1
  634. package/src/runtime/maintenance/cleanup.ts +38 -24
  635. package/src/runtime/platform/browser-product-discovery.ts +174 -0
  636. package/src/runtime/platform/computer-platform.ts +14 -0
  637. package/src/runtime/platform/executable-discovery.ts +54 -0
  638. package/src/runtime/platform/fetch-http-server.ts +90 -0
  639. package/src/runtime/platform/service-inventory.ts +130 -0
  640. package/src/runtime/platform/service-manager.ts +146 -0
  641. package/src/runtime/platform/windows-host-discovery.ts +118 -0
  642. package/src/runtime/platform/windows-recovery-deployment.ts +67 -0
  643. package/src/runtime/plugins/action-application.ts +192 -0
  644. package/src/runtime/plugins/app-store-connect-adapter.ts +47 -35
  645. package/src/runtime/plugins/browser-adapter.ts +898 -135
  646. package/src/runtime/plugins/browser-automation-service.ts +33 -34
  647. package/src/runtime/plugins/browser-macos-bridge.ts +386 -46
  648. package/src/runtime/plugins/browser-manifest-surface.ts +75 -17
  649. package/src/runtime/plugins/browser-native-session-service.ts +64 -14
  650. package/src/runtime/plugins/browser-provider-registry.ts +2 -109
  651. package/src/runtime/plugins/browser-registration.ts +32 -0
  652. package/src/runtime/plugins/browser-runtime-contract.ts +2 -154
  653. package/src/runtime/plugins/browser-runtime.ts +55 -10
  654. package/src/runtime/plugins/browser-session-authority.ts +101 -291
  655. package/src/runtime/plugins/browser-session-legacy-migration.ts +203 -0
  656. package/src/runtime/plugins/browser-session-store.ts +243 -80
  657. package/src/runtime/plugins/browser-session-types.ts +2 -98
  658. package/src/runtime/plugins/capability-authorization-grants.ts +272 -59
  659. package/src/runtime/plugins/catalog-trust.ts +82 -0
  660. package/src/runtime/plugins/computer-chatgpt-browser-adapter-installer.ts +219 -0
  661. package/src/runtime/plugins/computer-chatgpt-macos-target.ts +891 -0
  662. package/src/runtime/plugins/computer-registration.ts +1050 -0
  663. package/src/runtime/plugins/config-store.ts +119 -0
  664. package/src/runtime/plugins/desktop-operator-external-policy.ts +964 -0
  665. package/src/runtime/plugins/desktop-operator-registration.ts +123 -12
  666. package/src/runtime/plugins/errors.ts +8 -1
  667. package/src/runtime/plugins/external-adapter.ts +82 -323
  668. package/src/runtime/plugins/external-provider-policy.ts +48 -0
  669. package/src/runtime/plugins/external-registration.ts +30 -2
  670. package/src/runtime/plugins/external-unix-socket-probe.cjs +9 -3
  671. package/src/runtime/plugins/external-unix-socket.ts +64 -193
  672. package/src/runtime/plugins/first-party-external-registration.ts +163 -0
  673. package/src/runtime/plugins/first-party-registry.ts +3 -1
  674. package/src/runtime/plugins/github-adapter.ts +1 -2
  675. package/src/runtime/plugins/gmail-adapter.ts +29 -8
  676. package/src/runtime/plugins/google-calendar-adapter.ts +8 -8
  677. package/src/runtime/plugins/google-shared.ts +45 -53
  678. package/src/runtime/plugins/google-tasks-adapter.ts +8 -8
  679. package/src/runtime/plugins/ios-adapter.ts +2 -3
  680. package/src/runtime/plugins/lightweight-action.ts +208 -2
  681. package/src/runtime/plugins/local-system-adapter.ts +192 -2
  682. package/src/runtime/plugins/macos-capability-broker.ts +15 -105
  683. package/src/runtime/plugins/managed-process-adapter.ts +12 -5
  684. package/src/runtime/plugins/plugin-action-sidecar.ts +17 -13
  685. package/src/runtime/plugins/plugin-management-adapter.ts +1 -1
  686. package/src/runtime/plugins/resend-adapter.ts +15 -24
  687. package/src/runtime/plugins/store.ts +1003 -387
  688. package/src/runtime/plugins/types.ts +28 -1
  689. package/src/runtime/plugins/uu-remote-rescue-registration.ts +155 -0
  690. package/src/runtime/plugins/windows-host-recovery-install.ts +68 -0
  691. package/src/runtime/plugins/windows-host-recovery-registration.ts +85 -0
  692. package/src/runtime/plugins/xiaohongshu-publish.ts +102 -430
  693. package/src/runtime/projections/controller-context.ts +12 -6
  694. package/src/runtime/projections/git-status-sampler.ts +73 -22
  695. package/src/runtime/projections/invalidation.ts +7 -3
  696. package/src/runtime/projections/materialized-view.ts +93 -43
  697. package/src/runtime/recovery/actions.ts +3 -3
  698. package/src/runtime/recovery/capability-action-application.ts +229 -0
  699. package/src/runtime/recovery/index.ts +3 -0
  700. package/src/runtime/recovery/lifecycle-inventory.ts +338 -0
  701. package/src/runtime/recovery/local-jobs-repair.ts +14 -14
  702. package/src/runtime/recovery/maintenance-executor.ts +701 -168
  703. package/src/runtime/recovery/quarantine-retention.ts +256 -0
  704. package/src/runtime/recovery/store.ts +29 -11
  705. package/src/runtime/release/identity.ts +6 -0
  706. package/src/runtime/release/release-coordinator.ts +296 -0
  707. package/src/runtime/release/release-session.ts +716 -0
  708. package/src/runtime/release/release-state-migration.ts +25 -0
  709. package/src/runtime/resources/leases/store.ts +56 -25
  710. package/src/runtime/root/active-execution-power-assertion.ts +139 -0
  711. package/src/runtime/root/assistant-learning-loop.ts +45 -0
  712. package/src/runtime/root/browser-session-composition.ts +59 -0
  713. package/src/runtime/root/computer-composition.ts +376 -0
  714. package/src/runtime/root/computer-target-composition.ts +16 -0
  715. package/src/runtime/root/computer-target-persistence.ts +39 -0
  716. package/src/runtime/root/controller-progression-composition.ts +192 -0
  717. package/src/runtime/root/controller-round-composition.ts +126 -0
  718. package/src/runtime/root/controller-services.ts +2 -0
  719. package/src/runtime/root/deployment-topology.ts +106 -0
  720. package/src/runtime/root/entry.ts +8 -6
  721. package/src/runtime/root/gateway-adapter.ts +3 -3
  722. package/src/runtime/root/known-good-recovery.ts +184 -0
  723. package/src/runtime/root/local-bridge.ts +5 -3
  724. package/src/runtime/root/mcp-transport.ts +116 -23
  725. package/src/runtime/root/ownership.ts +261 -9
  726. package/src/runtime/root/package-connector-service.ts +212 -74
  727. package/src/runtime/root/package-runtime-release.ts +199 -33
  728. package/src/runtime/root/package-runtime-service.ts +77 -108
  729. package/src/runtime/root/release-execution-canary.ts +103 -0
  730. package/src/runtime/root/release-loader.ts +150 -0
  731. package/src/runtime/root/release-manifest.ts +185 -7
  732. package/src/runtime/root/release-materialize.ts +474 -31
  733. package/src/runtime/root/release-store.ts +425 -37
  734. package/src/runtime/root/runtime-lane.ts +191 -0
  735. package/src/runtime/root/runtime.ts +379 -32
  736. package/src/runtime/root/scheduled-controller-composition.ts +76 -0
  737. package/src/runtime/root/scheduler.ts +12 -4
  738. package/src/runtime/root/service-runner.ts +3 -3
  739. package/src/runtime/root/service.ts +73 -45
  740. package/src/runtime/root/status.ts +49 -0
  741. package/src/runtime/root/types.ts +55 -3
  742. package/src/runtime/root/workflow-supervisor-composition.ts +493 -0
  743. package/src/runtime/root/workflow-supervisor-runtime.ts +209 -0
  744. package/src/runtime/root/write-fence.ts +50 -2
  745. package/src/runtime/safe-tooling/google-credential-store.ts +76 -21
  746. package/src/runtime/safe-tooling/google-oauth-broker.ts +25 -7
  747. package/src/runtime/safe-tooling/workspace-auth.ts +1 -1
  748. package/src/runtime/shared/bounded-child-supervisor.ts +9 -1
  749. package/src/runtime/shared/local-bridge-surface.ts +1 -1
  750. package/src/runtime/shared/process-environment.ts +36 -10
  751. package/src/runtime/shared/response-budget.ts +1 -3
  752. package/src/runtime/shared/storage-capacity.ts +68 -0
  753. package/src/runtime/standalone-recovery/controller-home-migration.ts +1108 -0
  754. package/src/runtime/standalone-recovery/core.ts +4609 -495
  755. package/src/runtime/standalone-recovery/entry.ts +642 -81
  756. package/src/runtime/standalone-recovery/independent-host-rescue.ts +172 -0
  757. package/src/runtime/standalone-recovery/installer.ts +399 -177
  758. package/src/runtime/standalone-recovery/mcp-server.ts +79 -0
  759. package/src/runtime/standalone-recovery/mutation-identity-contract.ts +21 -0
  760. package/src/runtime/standalone-recovery/operation-lock.ts +160 -0
  761. package/src/runtime/standalone-recovery/performance.ts +173 -0
  762. package/src/runtime/standalone-recovery/release.ts +58 -5
  763. package/src/runtime/standalone-recovery/service-labels.ts +5 -2
  764. package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +5 -2
  765. package/src/runtime/watchdog/workflow-watchdog.ts +1 -1
  766. package/src/runtime/workflow/schedules/browser-probe.ts +17 -6
  767. package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +11 -4
  768. package/src/runtime/workflow/schedules/engine.ts +298 -484
  769. package/src/runtime/workflow/schedules/pending-activation.ts +1 -1
  770. package/src/runtime/workflow/schedules/settlement.ts +2 -191
  771. package/src/runtime/workflow/schedules/store.ts +2 -607
  772. package/src/runtime/workflow/schedules/types.ts +2 -127
  773. package/src/runtime/workflow/schedules/work-continuation.ts +220 -16
  774. package/src/runtime/workflows/first-party/xiaohongshu.ts +122 -0
  775. package/src/runtime/workflows/runtime.ts +482 -0
  776. package/src/testing/test-governance.ts +95 -30
  777. package/supervisor/chatgpt-conversation.ts +23 -0
  778. package/supervisor/client.ts +201 -0
  779. package/supervisor/control-plane.ts +868 -0
  780. package/supervisor/entry.ts +15 -0
  781. package/supervisor/forge-validators.ts +80 -0
  782. package/supervisor/index.ts +5 -0
  783. package/supervisor/native-browser-adapter.ts +786 -0
  784. package/supervisor/native-messaging/host.ts +39 -0
  785. package/supervisor/native-messaging/manifest.ts +26 -0
  786. package/supervisor/native-messaging/protocol.ts +27 -0
  787. package/supervisor/paths.ts +18 -0
  788. package/supervisor/protocol.ts +202 -0
  789. package/supervisor/server.ts +404 -0
  790. package/supervisor/store.ts +1451 -0
  791. package/supervisor/tsconfig.json +8 -0
  792. package/supervisor/types.ts +255 -0
  793. package/assets/templates/helpers/archive-architecture-request.sh +0 -244
  794. package/docs/architecture/history/README.md +0 -7
  795. package/docs/architecture/history/chatgpt-handoff-facade.md +0 -397
  796. package/docs/architecture/history/global-hook-runtime.md +0 -166
  797. package/docs/architecture/history/ios-semantic-automation-provider-v2.md +0 -170
  798. package/docs/architecture/requests/archive/2026/20260528-154740-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
  799. package/docs/architecture/requests/archive/2026/20260528-154816-assets-hooks-assets-hooks-hook-input-sh.md +0 -59
  800. package/docs/architecture/requests/archive/2026/20260528-161851-ai-harness-workflow-contract-json-ai-harness-workflow-contract-json.md +0 -59
  801. package/docs/architecture/requests/archive/2026/20260528-161853-scripts-check-task-workflow-sh-scripts-check-task-workflow-sh.md +0 -59
  802. package/docs/architecture/requests/archive/2026/20260528-161911-assets-workflow-contract-v1-json-assets-workflow-contract-v1-json.md +0 -59
  803. package/docs/architecture/requests/archive/2026/20260528-222416-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
  804. package/docs/architecture/requests/archive/2026/20260528-222444-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
  805. package/docs/architecture/requests/archive/2026/20260528-222457-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
  806. package/docs/architecture/requests/archive/2026/20260528-222648-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
  807. package/docs/architecture/requests/archive/2026/20260528-222705-ai-hooks-ai-hooks-worktree-guard-sh.md +0 -59
  808. package/docs/architecture/requests/archive/2026/20260528-222726-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  809. package/docs/architecture/requests/archive/2026/20260528-222727-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  810. package/docs/architecture/requests/archive/2026/20260528-224736-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
  811. package/docs/architecture/requests/archive/2026/20260528-233259-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  812. package/docs/architecture/requests/archive/2026/20260528-233335-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
  813. package/docs/architecture/requests/archive/2026/20260528-233456-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  814. package/docs/architecture/requests/archive/2026/20260528-233457-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
  815. package/docs/architecture/requests/archive/2026/20260528-233637-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  816. package/docs/architecture/requests/archive/2026/20260528-233638-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
  817. package/docs/architecture/requests/archive/2026/20260529-000322-root-package-json.md +0 -59
  818. package/docs/architecture/requests/archive/2026/20260529-004238-ai-hooks-ai-hooks-lib-workflow-state-sh.md +0 -59
  819. package/docs/architecture/requests/archive/2026/20260529-020654-ai-harness-policy-json-ai-harness-policy-json.md +0 -63
  820. package/docs/architecture/requests/archive/2026/20260529-094236-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -60
  821. package/docs/architecture/requests/archive/2026/20260529-094323-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -60
  822. package/docs/architecture/requests/archive/2026/20260529-094331-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -60
  823. package/docs/architecture/requests/archive/2026/20260529-094339-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -60
  824. package/docs/architecture/requests/archive/2026/20260529-094430-assets-hooks-assets-hooks-session-start-context-sh.md +0 -60
  825. package/docs/architecture/requests/archive/2026/20260529-094446-ai-hooks-ai-hooks-session-start-context-sh.md +0 -60
  826. package/docs/architecture/requests/archive/2026/20260613-002040-runtime-harness-hook-adapters.md +0 -68
  827. package/docs/architecture/requests/archive/2026/root.md +0 -68
  828. package/docs/architecture/requests/archive/2026/runtime-harness-hook-adapters.md +0 -76
  829. package/docs/architecture/requests/archive/2026/verification-evals-checks.md +0 -68
  830. package/docs/architecture/requests/archive/2026/workflow-engine-contract-assets.md +0 -69
  831. package/scripts/archive-architecture-request.sh +0 -4
  832. package/scripts/benchmark-background-check-overlap.ts +0 -228
  833. package/scripts/benchmark-controller-hotpath.ts +0 -212
  834. package/scripts/benchmark-controller-round2.ts +0 -139
  835. package/scripts/benchmark-ios-agent-device.ts +0 -514
  836. package/scripts/benchmark-mcp-host.sh +0 -117
  837. package/scripts/benchmark-mcp-transport.ts +0 -170
  838. package/scripts/benchmark-quality-harness.ts +0 -146
  839. package/scripts/benchmark-route-session-concurrency.ts +0 -915
  840. package/scripts/benchmark-thin-harness-gateway-ab.ts +0 -632
  841. package/scripts/benchmark-thin-harness-mcp-e2e.ts +0 -498
  842. package/scripts/benchmark-thin-harness.ts +0 -251
  843. package/scripts/benchmark-typescript-navigation.ts +0 -186
  844. package/scripts/benchmark-work-efficiency.ts +0 -334
  845. package/scripts/build-controller-ui.ts +0 -28
  846. package/scripts/check-npm-release.sh +0 -32
  847. package/scripts/check-public-release-surface.sh +0 -19
  848. package/scripts/check-release-published.sh +0 -57
  849. package/scripts/check-release-readiness.sh +0 -37
  850. package/scripts/check-release-version.mjs +0 -74
  851. package/scripts/check-tarball-install-smoke.sh +0 -67
  852. package/scripts/package-source-archive.sh +0 -147
  853. package/scripts/public-release-files.txt +0 -39
  854. package/scripts/public-release.ts +0 -174
  855. package/scripts/publish-release-tarball.sh +0 -27
  856. package/scripts/route-nl-vs-ts-eval.ts +0 -679
  857. package/scripts/run-skill-evals.ts +0 -1022
  858. package/scripts/stage-runtime-release.ts +0 -39
  859. package/src/cli/controller/progress.ts +0 -656
  860. package/src/cli/controller/work-mode.ts +0 -181
  861. package/src/cli/local-bridge/console-assets.ts +0 -17
  862. package/src/cli/local-bridge/dashboard.ts +0 -17
  863. package/src/cli/local-bridge/frontend/src/App.tsx +0 -10
  864. package/src/cli/local-bridge/frontend/src/components/Button.tsx +0 -1
  865. package/src/cli/local-bridge/frontend/src/components/DetailPane.tsx +0 -3
  866. package/src/cli/local-bridge/frontend/src/components/SearchField.tsx +0 -1
  867. package/src/cli/local-bridge/frontend/src/components/SectionHeader.tsx +0 -1
  868. package/src/cli/local-bridge/frontend/src/components/Segmented.tsx +0 -1
  869. package/src/cli/local-bridge/frontend/src/components/StatusText.tsx +0 -3
  870. package/src/cli/local-bridge/frontend/src/design/icons.tsx +0 -11
  871. package/src/cli/local-bridge/frontend/src/design/tokens.css +0 -8
  872. package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +0 -153
  873. package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +0 -37
  874. package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +0 -183
  875. package/src/cli/local-bridge/frontend/src/features/repositories/RepositoriesView.tsx +0 -2
  876. package/src/cli/local-bridge/frontend/src/features/system/SystemView.tsx +0 -2
  877. package/src/cli/local-bridge/frontend/src/features/work/WorkView.tsx +0 -4
  878. package/src/cli/local-bridge/frontend/src/lib/api.ts +0 -30
  879. package/src/cli/local-bridge/frontend/src/lib/format.ts +0 -4
  880. package/src/cli/local-bridge/frontend/src/lib/routes.ts +0 -7
  881. package/src/cli/local-bridge/frontend/src/main.tsx +0 -1
  882. package/src/cli/local-bridge/frontend/src/shell/AppShell.tsx +0 -1
  883. package/src/cli/local-bridge/frontend/src/shell/CommandBar.tsx +0 -2
  884. package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +0 -4
  885. package/src/cli/local-bridge/frontend/src/styles.css +0 -28
  886. package/src/cli/local-bridge/frontend/src/types.ts +0 -15
  887. package/src/cli/local-bridge/frontend/src/vite-env.d.ts +0 -1
  888. package/src/cli/local-bridge/frontend/vite.config.ts +0 -27
  889. package/src/cli/local-bridge/ui-dist/app.css +0 -1
  890. package/src/cli/local-bridge/ui-dist/app.js +0 -11228
  891. package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +0 -385
  892. package/src/runtime/control-plane/execution/work-finalization-service.ts +0 -1913
  893. package/src/runtime/control-plane/execution/work-path-scope.ts +0 -37
  894. package/src/runtime/control-plane/execution/work-task-receipt.ts +0 -449
  895. package/src/runtime/control-plane/facade/controller-round-relay.ts +0 -1118
  896. package/src/runtime/control-plane/facade/work-admission-policy.ts +0 -93
  897. package/src/runtime/control-plane/facade/work-task-projection.ts +0 -66
  898. package/src/runtime/control-plane/routing/index.ts +0 -1
  899. package/src/runtime/control-plane/routing/route-policy.ts +0 -382
  900. package/src/runtime/control-plane/routing/workspace-admission.ts +0 -70
@@ -19,8 +19,7 @@ import {
19
19
  releaseControllerCheckSubscription,
20
20
  runControllerCheckAsync,
21
21
  } from '../../../cli/controller/check-runner';
22
- import { repositoryControllerRoot } from '../../../cli/repositories/controller-home';
23
- import type { RepositoryRecord } from '../../../cli/repositories/types';
22
+ import { commandExecutionScopeKey, type RepositoryCommandScopeTarget } from '../../../cli/repositories/command-scope';
24
23
  import { readJsonFile, sanitizeFileComponent, writeJsonAtomic } from '../../shared/json-files';
25
24
  import {
26
25
  defaultProcessIdentityProbe,
@@ -30,6 +29,17 @@ import {
30
29
  } from '../../shared/process-identity';
31
30
  import { terminateProcessTree } from '../../shared/process-tree';
32
31
  import { runBoundedProcess } from '../thin-harness/async-process';
32
+ import { recordProcessHandleIndexEntry } from './handle-index';
33
+ import {
34
+ FORGE_INSTANCE_PROCESS_SCOPE_KEY,
35
+ isWorkspaceProcessScopeKey,
36
+ legacyWorkspaceScopeRoot,
37
+ normalizeProcessScopeKey,
38
+ processScopeExecutionTarget,
39
+ processScopeFromKey,
40
+ processScopeKey,
41
+ processScopeRoot,
42
+ } from './process-scope';
33
43
  import { PROCESS_LOG_TAIL_BYTES, type ProcessHandle, type ProcessLogSlice, type WaitProcessOptions } from './types';
34
44
 
35
45
  const EMPTY_EFFECTS = {
@@ -66,7 +76,12 @@ interface LightweightExitObservation {
66
76
  interface LightweightEntry {
67
77
  processId: string;
68
78
  controllerHome: string;
69
- repoId: string;
79
+ /** Canonical Process scope partition key (`repo_*` repository id, or the ForgeInstance scope key). */
80
+ scopeKey: string;
81
+ /** Repository placement when this handle targets a repository; absent for ForgeInstance targets. */
82
+ repoId?: string;
83
+ /** Owning principal recorded from the invoking MCP/Runtime context. */
84
+ principalId?: string;
70
85
  workId?: string;
71
86
  commandId: string;
72
87
  requestFingerprint: string;
@@ -93,9 +108,17 @@ interface LightweightEntry {
93
108
 
94
109
  const entries = new Map<string, LightweightEntry>();
95
110
 
111
+ export function hasActiveLightweightProcesses(controllerHome: string): boolean {
112
+ return [...entries.values()].some((entry) => (
113
+ entry.controllerHome === controllerHome && entry.result === undefined
114
+ ));
115
+ }
116
+
96
117
  interface LightweightRunningReceipt {
97
118
  schemaVersion: 1;
98
- repoId: string;
119
+ /** Canonical scope partition key. Legacy receipts carry only `repoId`. */
120
+ scopeKey?: string;
121
+ repoId?: string;
99
122
  processId: string;
100
123
  commandId?: string;
101
124
  requestFingerprint?: string;
@@ -107,7 +130,9 @@ interface LightweightRunningReceipt {
107
130
 
108
131
  interface LightweightTerminalReceipt {
109
132
  schemaVersion: 1;
110
- repoId: string;
133
+ /** Canonical scope partition key. Legacy receipts carry only `repoId`. */
134
+ scopeKey?: string;
135
+ repoId?: string;
111
136
  processId: string;
112
137
  commandId?: string;
113
138
  requestFingerprint?: string;
@@ -115,20 +140,44 @@ interface LightweightTerminalReceipt {
115
140
  handle: ProcessHandle;
116
141
  }
117
142
 
118
- function runningReceiptRoot(controllerHome: string, repoId: string): string {
119
- return join(repositoryControllerRoot(controllerHome, repoId), 'process-runtime', 'lightweight-running');
143
+ function runningReceiptRoot(controllerHome: string, scopeKey: string): string {
144
+ return join(processScopeRoot(controllerHome, scopeKey), 'process-runtime', 'lightweight-running');
145
+ }
146
+
147
+ function runningReceiptPath(controllerHome: string, scopeKey: string, processId: string): string {
148
+ return join(runningReceiptRoot(controllerHome, scopeKey), `${sanitizeFileComponent(processId)}.json`);
120
149
  }
121
150
 
122
- function runningReceiptPath(controllerHome: string, repoId: string, processId: string): string {
123
- return join(runningReceiptRoot(controllerHome, repoId), `${sanitizeFileComponent(processId)}.json`);
151
+ function terminalReceiptRoot(controllerHome: string, scopeKey: string): string {
152
+ return join(processScopeRoot(controllerHome, scopeKey), 'process-runtime', 'lightweight-terminal');
124
153
  }
125
154
 
126
- function terminalReceiptRoot(controllerHome: string, repoId: string): string {
127
- return join(repositoryControllerRoot(controllerHome, repoId), 'process-runtime', 'lightweight-terminal');
155
+ function terminalReceiptPath(controllerHome: string, scopeKey: string, processId: string): string {
156
+ return join(terminalReceiptRoot(controllerHome, scopeKey), `${sanitizeFileComponent(processId)}.json`);
128
157
  }
129
158
 
130
- function terminalReceiptPath(controllerHome: string, repoId: string, processId: string): string {
131
- return join(terminalReceiptRoot(controllerHome, repoId), `${sanitizeFileComponent(processId)}.json`);
159
+ /**
160
+ * Bounded migration read: a workspace-scoped receipt written before the
161
+ * workspace partition existed still resolves, instead of reporting a running
162
+ * command as missing. Repository scopes never take this path.
163
+ */
164
+ function existingReceiptPath(
165
+ controllerHome: string,
166
+ scopeKey: string,
167
+ processId: string,
168
+ build: (controllerHome: string, scopeKey: string, processId: string) => string,
169
+ ): string {
170
+ const current = build(controllerHome, scopeKey, processId);
171
+ if (existsSync(current) || !isWorkspaceProcessScopeKey(scopeKey)) return current;
172
+ const legacyRoot = legacyWorkspaceScopeRoot(controllerHome, scopeKey);
173
+ if (!legacyRoot) return current;
174
+ const legacy = join(
175
+ legacyRoot,
176
+ 'process-runtime',
177
+ build === runningReceiptPath ? 'lightweight-running' : 'lightweight-terminal',
178
+ `${sanitizeFileComponent(processId)}.json`,
179
+ );
180
+ return existsSync(legacy) ? legacy : current;
132
181
  }
133
182
 
134
183
  function boundedAppend(current: string, chunk: string, maxBytes: number): string {
@@ -163,8 +212,8 @@ function captureProcessIdentity(pid: number): ExpectedProcessIdentity | undefine
163
212
  return { pid, processStartTime, executableFingerprint: executableFingerprint(command) };
164
213
  }
165
214
 
166
- function removeRunningReceipt(controllerHome: string, repoId: string, processId: string): void {
167
- try { rmSync(runningReceiptPath(controllerHome, repoId, processId), { force: true }); } catch { /* best effort */ }
215
+ function removeRunningReceipt(controllerHome: string, scopeKey: string, processId: string): void {
216
+ try { rmSync(runningReceiptPath(controllerHome, scopeKey, processId), { force: true }); } catch { /* best effort */ }
168
217
  }
169
218
 
170
219
  function persistRunningReceipt(entry: LightweightEntry, force = false): void {
@@ -176,12 +225,13 @@ function persistRunningReceipt(entry: LightweightEntry, force = false): void {
176
225
  if (!force && entry.runningReceiptUpdatedAtMs !== undefined
177
226
  && now - entry.runningReceiptUpdatedAtMs < RUNNING_RECEIPT_PERSIST_INTERVAL_MS) return;
178
227
  try {
179
- const root = runningReceiptRoot(entry.controllerHome, entry.repoId);
228
+ const root = runningReceiptRoot(entry.controllerHome, entry.scopeKey);
180
229
  mkdirSync(root, { recursive: true, mode: 0o700 });
181
- const path = runningReceiptPath(entry.controllerHome, entry.repoId, entry.processId);
230
+ const path = runningReceiptPath(entry.controllerHome, entry.scopeKey, entry.processId);
182
231
  const receipt: LightweightRunningReceipt = {
183
232
  schemaVersion: 1,
184
- repoId: entry.repoId,
233
+ scopeKey: entry.scopeKey,
234
+ ...(entry.repoId ? { repoId: entry.repoId } : {}),
185
235
  processId: entry.processId,
186
236
  commandId: entry.commandId,
187
237
  requestFingerprint: entry.requestFingerprint,
@@ -198,12 +248,12 @@ function persistRunningReceipt(entry: LightweightEntry, force = false): void {
198
248
  }
199
249
  }
200
250
 
201
- function readRunningReceipt(controllerHome: string, repoId: string, processId: string): LightweightRunningReceipt | undefined {
202
- const path = runningReceiptPath(controllerHome, repoId, processId);
251
+ function readRunningReceipt(controllerHome: string, scopeKey: string, processId: string): LightweightRunningReceipt | undefined {
252
+ const path = existingReceiptPath(controllerHome, scopeKey, processId, runningReceiptPath);
203
253
  if (!existsSync(path)) return undefined;
204
254
  try {
205
255
  const receipt = readJsonFile<LightweightRunningReceipt>(path);
206
- if (receipt.schemaVersion !== 1 || receipt.repoId !== repoId || receipt.processId !== processId) return undefined;
256
+ if (receipt.schemaVersion !== 1 || (receipt.scopeKey ?? receipt.repoId) !== scopeKey || receipt.processId !== processId) return undefined;
207
257
  if (receipt.handle?.processId !== processId || receipt.handle.completed) return undefined;
208
258
  return receipt;
209
259
  } catch {
@@ -255,18 +305,19 @@ function pruneTerminalReceipts(root: string, keepPath: string): void {
255
305
 
256
306
  function persistTerminalReceipt(controllerHome: string, entry: LightweightEntry): void {
257
307
  if (!entry.result || !entry.finishedAtMs) return;
258
- const existing = readTerminalReceipt(controllerHome, entry.repoId, entry.processId);
308
+ const existing = readTerminalReceipt(controllerHome, entry.scopeKey, entry.processId);
259
309
  if (existing) {
260
- removeRunningReceipt(controllerHome, entry.repoId, entry.processId);
310
+ removeRunningReceipt(controllerHome, entry.scopeKey, entry.processId);
261
311
  return;
262
312
  }
263
313
  try {
264
- const root = terminalReceiptRoot(controllerHome, entry.repoId);
314
+ const root = terminalReceiptRoot(controllerHome, entry.scopeKey);
265
315
  mkdirSync(root, { recursive: true, mode: 0o700 });
266
- const path = terminalReceiptPath(controllerHome, entry.repoId, entry.processId);
316
+ const path = terminalReceiptPath(controllerHome, entry.scopeKey, entry.processId);
267
317
  const receipt: LightweightTerminalReceipt = {
268
318
  schemaVersion: 1,
269
- repoId: entry.repoId,
319
+ scopeKey: entry.scopeKey,
320
+ ...(entry.repoId ? { repoId: entry.repoId } : {}),
270
321
  processId: entry.processId,
271
322
  commandId: entry.commandId,
272
323
  requestFingerprint: entry.requestFingerprint,
@@ -275,19 +326,19 @@ function persistTerminalReceipt(controllerHome: string, entry: LightweightEntry)
275
326
  };
276
327
  writeJsonAtomic(path, receipt);
277
328
  try { chmodSync(path, 0o600); } catch { /* Windows or restricted filesystem. */ }
278
- removeRunningReceipt(controllerHome, entry.repoId, entry.processId);
329
+ removeRunningReceipt(controllerHome, entry.scopeKey, entry.processId);
279
330
  pruneTerminalReceipts(root, path);
280
331
  } catch {
281
332
  // A receipt failure must never turn a completed local command into a failure.
282
333
  }
283
334
  }
284
335
 
285
- function readTerminalReceipt(controllerHome: string, repoId: string, processId: string): LightweightTerminalReceipt | undefined {
286
- const path = terminalReceiptPath(controllerHome, repoId, processId);
336
+ function readTerminalReceipt(controllerHome: string, scopeKey: string, processId: string): LightweightTerminalReceipt | undefined {
337
+ const path = existingReceiptPath(controllerHome, scopeKey, processId, terminalReceiptPath);
287
338
  if (!existsSync(path)) return undefined;
288
339
  try {
289
340
  const receipt = readJsonFile<LightweightTerminalReceipt>(path);
290
- if (receipt.schemaVersion !== 1 || receipt.repoId !== repoId || receipt.processId !== processId) return undefined;
341
+ if (receipt.schemaVersion !== 1 || (receipt.scopeKey ?? receipt.repoId) !== scopeKey || receipt.processId !== processId) return undefined;
291
342
  if (!receipt.handle?.completed || receipt.handle.processId !== processId) return undefined;
292
343
  const finishedAtMs = Date.parse(receipt.finishedAt);
293
344
  if (!Number.isFinite(finishedAtMs) || Date.now() - finishedAtMs > TERMINAL_RECEIPT_RETENTION_MS) {
@@ -317,24 +368,24 @@ function recoveredRequestMetrics(): LightweightCommandMetrics {
317
368
  */
318
369
  function findPersistedHandleForCommand(
319
370
  controllerHome: string,
320
- repoId: string,
371
+ scopeKey: string,
321
372
  commandId: string,
322
373
  requestFingerprint: string,
323
374
  ): ProcessHandle | undefined {
324
- const roots = [terminalReceiptRoot(controllerHome, repoId), runningReceiptRoot(controllerHome, repoId)];
375
+ const roots = [terminalReceiptRoot(controllerHome, scopeKey), runningReceiptRoot(controllerHome, scopeKey)];
325
376
  for (const root of roots) {
326
377
  if (!existsSync(root)) continue;
327
378
  for (const file of readdirSync(root)) {
328
379
  if (!file.endsWith('.json')) continue;
329
380
  try {
330
381
  const receipt = readJsonFile<LightweightRunningReceipt | LightweightTerminalReceipt>(join(root, file));
331
- if (receipt.schemaVersion !== 1 || receipt.repoId !== repoId || !receipt.processId) continue;
382
+ if (receipt.schemaVersion !== 1 || (receipt.scopeKey ?? receipt.repoId) !== scopeKey || !receipt.processId) continue;
332
383
  const persistedCommandId = receipt.commandId ?? receipt.handle?.commandId;
333
384
  if (persistedCommandId !== commandId) continue;
334
385
  if (!receipt.requestFingerprint || receipt.requestFingerprint !== requestFingerprint) {
335
386
  throw new Error(`PROCESS_REQUEST_CONFLICT: command id ${commandId} cannot be safely replayed after Runtime restart`);
336
387
  }
337
- return getLightweightProcessHandle(controllerHome, repoId, receipt.processId);
388
+ return getLightweightProcessHandle(controllerHome, scopeKey, receipt.processId);
338
389
  } catch (error) {
339
390
  if (error instanceof Error && error.message.startsWith('PROCESS_REQUEST_CONFLICT:')) throw error;
340
391
  // A corrupt or concurrently pruned receipt is not an execution result.
@@ -393,18 +444,21 @@ function persistRecoveredTerminalReceipt(
393
444
  receipt: LightweightRunningReceipt,
394
445
  handle: ProcessHandle,
395
446
  ): ProcessHandle {
396
- const existing = readTerminalReceipt(controllerHome, receipt.repoId, receipt.processId);
447
+ const scopeKey = receipt.scopeKey ?? receipt.repoId;
448
+ if (!scopeKey) return handle;
449
+ const existing = readTerminalReceipt(controllerHome, scopeKey, receipt.processId);
397
450
  if (existing) {
398
- removeRunningReceipt(controllerHome, receipt.repoId, receipt.processId);
451
+ removeRunningReceipt(controllerHome, scopeKey, receipt.processId);
399
452
  return existing.handle;
400
453
  }
401
454
  try {
402
- const root = terminalReceiptRoot(controllerHome, receipt.repoId);
455
+ const root = terminalReceiptRoot(controllerHome, scopeKey);
403
456
  mkdirSync(root, { recursive: true, mode: 0o700 });
404
- const path = terminalReceiptPath(controllerHome, receipt.repoId, receipt.processId);
457
+ const path = terminalReceiptPath(controllerHome, scopeKey, receipt.processId);
405
458
  const terminal: LightweightTerminalReceipt = {
406
459
  schemaVersion: 1,
407
- repoId: receipt.repoId,
460
+ scopeKey,
461
+ ...(receipt.repoId ? { repoId: receipt.repoId } : {}),
408
462
  processId: receipt.processId,
409
463
  commandId: receipt.commandId,
410
464
  requestFingerprint: receipt.requestFingerprint,
@@ -413,7 +467,7 @@ function persistRecoveredTerminalReceipt(
413
467
  };
414
468
  writeJsonAtomic(path, terminal);
415
469
  try { chmodSync(path, 0o600); } catch { /* Windows or restricted filesystem. */ }
416
- removeRunningReceipt(controllerHome, receipt.repoId, receipt.processId);
470
+ removeRunningReceipt(controllerHome, scopeKey, receipt.processId);
417
471
  pruneTerminalReceipts(root, path);
418
472
  } catch {
419
473
  // Recovery evidence persistence must not trigger command re-execution or unsafe signalling.
@@ -549,13 +603,16 @@ function entryHandle(entry: LightweightEntry): ProcessHandle {
549
603
 
550
604
  export interface StartLightweightCommandInput {
551
605
  controllerHome: string;
552
- repository: RepositoryRecord;
606
+ /** Repository identity is optional: an arbitrary workspace target carries a workspace scope key. */
607
+ repository: RepositoryCommandScopeTarget;
553
608
  execution: ExecuteRepositoryCommandInput;
554
609
  interactiveWaitMs: number;
555
610
  timeoutMs: number;
556
611
  maxOutputBytes?: number;
557
612
  workId?: string;
558
613
  commandId?: string;
614
+ /** Authenticated principal recorded with the handle for principal-bound attachment. */
615
+ principalId?: string;
559
616
  /** Start repository preparation on the next event-loop turn so the caller can receive a handle first. */
560
617
  deferStart?: boolean;
561
618
  /** Reuse an equivalent active local build/test even when a later caller has a different request id. */
@@ -582,10 +639,15 @@ export interface StartLightweightCheckInput {
582
639
  timeoutMs: number;
583
640
  workId?: string;
584
641
  commandId?: string;
642
+ /** Authenticated principal recorded with the handle for principal-bound attachment. */
643
+ principalId?: string;
585
644
  }
586
645
 
587
646
  export interface StartLightweightInternalProcessInput {
588
- repoId: string;
647
+ /** Canonical Process scope key. Defaults to `repoId` for repository-scoped internal processes. */
648
+ scopeKey?: string;
649
+ /** Repository placement when this process targets a repository; absent for ForgeInstance targets. */
650
+ repoId?: string;
589
651
  executable: string;
590
652
  args: readonly string[];
591
653
  cwd: string;
@@ -597,15 +659,21 @@ export interface StartLightweightInternalProcessInput {
597
659
  workId?: string;
598
660
  commandId?: string;
599
661
  signal?: AbortSignal;
662
+ /** Authenticated principal recorded with the handle for principal-bound attachment. */
663
+ principalId?: string;
600
664
  }
601
665
 
602
666
  export async function startLightweightRepositoryCommand(
603
667
  input: StartLightweightCommandInput,
604
668
  ): Promise<{ handle: ProcessHandle; metrics: LightweightCommandMetrics }> {
605
669
  sweep();
670
+ // Repository targets keep their repository partition; an arbitrary workspace
671
+ // target is scoped by its workspace id instead of a synthetic repository id.
672
+ const scope = processScopeFromKey(commandExecutionScopeKey(input.repository));
673
+ const scopeKey = processScopeKey(scope);
606
674
  const stableCommandId = input.commandId?.trim();
607
675
  const requestFingerprint = JSON.stringify({
608
- repoId: input.repository.repoId,
676
+ repoId: commandExecutionScopeKey(input.repository),
609
677
  command: input.execution.command,
610
678
  cwd: input.execution.cwd ?? '.',
611
679
  timeoutMs: input.timeoutMs,
@@ -614,7 +682,7 @@ export async function startLightweightRepositoryCommand(
614
682
  if (stableCommandId) {
615
683
  const existing = [...entries.values()].find((entry) => (
616
684
  entry.controllerHome === input.controllerHome
617
- && entry.repoId === input.repository.repoId
685
+ && entry.scopeKey === scopeKey
618
686
  && entry.commandId === stableCommandId
619
687
  ));
620
688
  if (existing) {
@@ -637,7 +705,7 @@ export async function startLightweightRepositoryCommand(
637
705
  }
638
706
  const recovered = findPersistedHandleForCommand(
639
707
  input.controllerHome,
640
- input.repository.repoId,
708
+ scopeKey,
641
709
  stableCommandId,
642
710
  requestFingerprint,
643
711
  );
@@ -645,7 +713,7 @@ export async function startLightweightRepositoryCommand(
645
713
  }
646
714
  if (input.reuseActiveEquivalent) {
647
715
  const existing = [...entries.values()].find((entry) => (
648
- entry.repoId === input.repository.repoId
716
+ entry.scopeKey === scopeKey
649
717
  && entry.requestFingerprint === requestFingerprint
650
718
  && entry.result === undefined
651
719
  ));
@@ -669,7 +737,9 @@ export async function startLightweightRepositoryCommand(
669
737
  const entry: LightweightEntry = {
670
738
  processId,
671
739
  controllerHome: input.controllerHome,
672
- repoId: input.repository.repoId,
740
+ scopeKey,
741
+ ...(scope.kind === 'repository' ? { repoId: commandExecutionScopeKey(input.repository) } : {}),
742
+ ...(input.principalId ? { principalId: input.principalId } : {}),
673
743
  workId: input.workId,
674
744
  commandId: stableCommandId || processId,
675
745
  requestFingerprint,
@@ -740,7 +810,31 @@ export async function startLightweightRepositoryCommand(
740
810
  // degradation is represented by RepositoryCommandExecution.evidenceError;
741
811
  // this catch is the final fail-safe for any later post-processing exception.
742
812
  if (entry.exitObservation && entry.result) return entry.result;
743
- throw error;
813
+
814
+ // Command preparation can fail before spawn (for example a repository-scope
815
+ // or external-filesystem grant denial). In deferred-start mode that rejection
816
+ // must belong to this lightweight Process; allowing it to escape would become
817
+ // an unhandled Runtime rejection and could terminate unrelated in-flight work.
818
+ const message = error instanceof Error ? error.message : String(error);
819
+ const failed: LightweightExecutionResult = {
820
+ ok: false,
821
+ exitCode: 1,
822
+ timedOut: false,
823
+ cancelled: false,
824
+ stdout: visibleOutput(entry.stdout, maxOutputBytes),
825
+ stderr: visibleOutput([entry.stderr, message].filter(Boolean).join('\n'), maxOutputBytes),
826
+ };
827
+ entry.result = failed;
828
+ entry.finishedAtMs = Date.now();
829
+ input.execution.signal?.removeEventListener('abort', onCallerAbort);
830
+ try {
831
+ input.onCompleted?.(failed);
832
+ } catch (callbackError) {
833
+ const callbackMessage = callbackError instanceof Error ? callbackError.message : String(callbackError);
834
+ failed.stderr = visibleOutput([failed.stderr, callbackMessage].filter(Boolean).join('\n'), maxOutputBytes);
835
+ }
836
+ persistTerminalReceipt(input.controllerHome, entry);
837
+ return failed;
744
838
  });
745
839
  entry.promise = input.deferStart
746
840
  ? new Promise<LightweightExecutionResult>((resolve, reject) => {
@@ -750,6 +844,16 @@ export async function startLightweightRepositoryCommand(
750
844
  })
751
845
  : startExecution();
752
846
  entries.set(processId, entry);
847
+ // Instance-level locator: a lightweight handle must be attachable from the
848
+ // returned processId alone, including after Runtime memory loss.
849
+ recordProcessHandleIndexEntry(input.controllerHome, {
850
+ processId,
851
+ lane: 'lightweight',
852
+ target: processScopeExecutionTarget(input.controllerHome, processScopeFromKey(entry.scopeKey)),
853
+ principalId: entry.principalId,
854
+ workId: entry.workId,
855
+ commandId: entry.commandId,
856
+ });
753
857
  persistRunningReceipt(entry, true);
754
858
 
755
859
  if (entry.interactiveWaitMs > 0) {
@@ -781,18 +885,31 @@ export async function startLightweightInternalProcess(
781
885
  input: StartLightweightInternalProcessInput,
782
886
  ): Promise<{ handle: ProcessHandle; metrics: LightweightCommandMetrics }> {
783
887
  sweep();
888
+ const repoId = input.repoId?.trim() || undefined;
889
+ const scopeKey = normalizeProcessScopeKey(input.scopeKey?.trim() || repoId || '');
890
+ const scope = processScopeFromKey(scopeKey);
784
891
  const stableCommandId = input.commandId?.trim();
892
+ // Retry identity is commandId + fingerprint(scope target, action, principal).
893
+ // An instance-scope request id is never a naked global namespace: a different
894
+ // principal presenting the same request id fails closed as a request conflict
895
+ // instead of attaching to another principal's process.
896
+ const principalId = input.principalId?.trim() || null;
785
897
  const requestFingerprint = JSON.stringify({
786
- repoId: input.repoId,
898
+ scopeKey,
899
+ repoId: repoId ?? null,
787
900
  executable: input.executable,
788
901
  args: input.args,
789
902
  cwd: input.cwd,
790
903
  timeoutMs: input.timeoutMs,
904
+ // Only a principal-bound lane (the ForgeInstance host command lane) adds the
905
+ // principal to retry identity, so existing repository/plugin fingerprints
906
+ // keep their historical value instead of failing closed after an upgrade.
907
+ ...(principalId ? { principalId } : {}),
791
908
  });
792
909
  if (stableCommandId) {
793
910
  const existing = [...entries.values()].find((entry) => (
794
911
  entry.controllerHome === input.controllerHome
795
- && entry.repoId === input.repoId
912
+ && entry.scopeKey === scopeKey
796
913
  && entry.commandId === stableCommandId
797
914
  ));
798
915
  if (existing) {
@@ -815,7 +932,7 @@ export async function startLightweightInternalProcess(
815
932
  }
816
933
  const recovered = findPersistedHandleForCommand(
817
934
  input.controllerHome,
818
- input.repoId,
935
+ scopeKey,
819
936
  stableCommandId,
820
937
  requestFingerprint,
821
938
  );
@@ -828,7 +945,9 @@ export async function startLightweightInternalProcess(
828
945
  const entry: LightweightEntry = {
829
946
  processId,
830
947
  controllerHome: input.controllerHome,
831
- repoId: input.repoId,
948
+ scopeKey,
949
+ ...(repoId ? { repoId } : {}),
950
+ ...(input.principalId?.trim() ? { principalId: input.principalId.trim() } : {}),
832
951
  workId: input.workId,
833
952
  commandId: stableCommandId || processId,
834
953
  requestFingerprint,
@@ -876,6 +995,14 @@ export async function startLightweightInternalProcess(
876
995
  return result;
877
996
  });
878
997
  entries.set(processId, entry);
998
+ recordProcessHandleIndexEntry(entry.controllerHome, {
999
+ processId,
1000
+ lane: 'lightweight',
1001
+ target: processScopeExecutionTarget(entry.controllerHome, processScopeFromKey(entry.scopeKey)),
1002
+ principalId: entry.principalId,
1003
+ workId: entry.workId,
1004
+ commandId: entry.commandId,
1005
+ });
879
1006
  persistRunningReceipt(entry, true);
880
1007
 
881
1008
  if (entry.interactiveWaitMs > 0) {
@@ -903,6 +1030,68 @@ export async function startLightweightInternalProcess(
903
1030
  };
904
1031
  }
905
1032
 
1033
+ export interface StartLightweightHostCommandInput {
1034
+ controllerHome: string;
1035
+ /** Typed argv command; `command[0]` is the executable. */
1036
+ command?: readonly string[];
1037
+ /** Explicit broad host-shell form. Authorized by the same host process grant as argv. */
1038
+ shellCommand?: string;
1039
+ cwd: string;
1040
+ env?: NodeJS.ProcessEnv;
1041
+ interactiveWaitMs: number;
1042
+ timeoutMs: number;
1043
+ maxOutputBytes?: number;
1044
+ workId?: string;
1045
+ commandId?: string;
1046
+ signal?: AbortSignal;
1047
+ principalId?: string;
1048
+ }
1049
+
1050
+ /** Platform shell used for the explicit `shell_command` form. Mirrors the Process Runner convention. */
1051
+ export function hostShellInvocation(shellCommand: string): readonly string[] {
1052
+ const command = shellCommand.trim();
1053
+ if (!command) throw new Error('HOST_COMMAND_SHELL_STRING_REQUIRED');
1054
+ return process.platform === 'win32'
1055
+ ? ['cmd.exe', '/c', command]
1056
+ : ['/bin/bash', '-lc', command];
1057
+ }
1058
+
1059
+ function hostCommandArgv(input: StartLightweightHostCommandInput): readonly string[] {
1060
+ const shellCommand = input.shellCommand?.trim();
1061
+ if (shellCommand) return hostShellInvocation(shellCommand);
1062
+ const argv = (input.command ?? []).map((entry) => String(entry));
1063
+ if (argv.length === 0 || !argv[0]) throw new Error('HOST_COMMAND_ARGV_REQUIRED');
1064
+ return argv;
1065
+ }
1066
+
1067
+ /**
1068
+ * Mode-free host-local command lane. The target is the ForgeInstance, `cwd` is
1069
+ * an execution argument, and no repository registration or checkout identity is
1070
+ * required. Authorization is the caller's responsibility: this lane performs no
1071
+ * command parsing and never becomes a path sandbox.
1072
+ */
1073
+ export async function startLightweightHostCommand(
1074
+ input: StartLightweightHostCommandInput,
1075
+ ): Promise<{ handle: ProcessHandle; metrics: LightweightCommandMetrics }> {
1076
+ const argv = hostCommandArgv(input);
1077
+ const executable = argv[0]!;
1078
+ return startLightweightInternalProcess({
1079
+ controllerHome: input.controllerHome,
1080
+ scopeKey: FORGE_INSTANCE_PROCESS_SCOPE_KEY,
1081
+ executable,
1082
+ args: argv.slice(1),
1083
+ cwd: input.cwd,
1084
+ env: input.env,
1085
+ interactiveWaitMs: input.interactiveWaitMs,
1086
+ timeoutMs: input.timeoutMs,
1087
+ maxOutputBytes: input.maxOutputBytes,
1088
+ workId: input.workId,
1089
+ commandId: input.commandId,
1090
+ signal: input.signal,
1091
+ principalId: input.principalId,
1092
+ });
1093
+ }
1094
+
906
1095
  export async function startLightweightControllerCheck(
907
1096
  input: StartLightweightCheckInput,
908
1097
  ): Promise<{ handle: ProcessHandle; metrics: LightweightCommandMetrics }> {
@@ -917,7 +1106,7 @@ export async function startLightweightControllerCheck(
917
1106
  if (stableCommandId) {
918
1107
  const existing = [...entries.values()].find((entry) => (
919
1108
  entry.controllerHome === input.controllerHome
920
- && entry.repoId === input.repoId
1109
+ && entry.scopeKey === input.repoId
921
1110
  && entry.commandId === stableCommandId
922
1111
  ));
923
1112
  if (existing) {
@@ -952,7 +1141,9 @@ export async function startLightweightControllerCheck(
952
1141
  const entry: LightweightEntry = {
953
1142
  processId,
954
1143
  controllerHome: input.controllerHome,
1144
+ scopeKey: input.repoId,
955
1145
  repoId: input.repoId,
1146
+ ...(input.principalId ? { principalId: input.principalId } : {}),
956
1147
  workId: input.workId,
957
1148
  commandId: stableCommandId || processId,
958
1149
  requestFingerprint,
@@ -974,6 +1165,7 @@ export async function startLightweightControllerCheck(
974
1165
  }, { once: true });
975
1166
  entry.promise = runControllerCheckAsync(input.repoRoot, input.checkId, {
976
1167
  requestedTimeoutMs: input.timeoutMs,
1168
+ storageAuthority: { controllerHome: input.controllerHome, repoId: input.repoId },
977
1169
  subscriberId: processId,
978
1170
  onSpawn: (pid) => {
979
1171
  entry.pid = pid;
@@ -1000,6 +1192,14 @@ export async function startLightweightControllerCheck(
1000
1192
  return result;
1001
1193
  });
1002
1194
  entries.set(processId, entry);
1195
+ recordProcessHandleIndexEntry(entry.controllerHome, {
1196
+ processId,
1197
+ lane: 'lightweight',
1198
+ target: processScopeExecutionTarget(entry.controllerHome, processScopeFromKey(entry.scopeKey)),
1199
+ principalId: entry.principalId,
1200
+ workId: entry.workId,
1201
+ commandId: entry.commandId,
1202
+ });
1003
1203
  persistRunningReceipt(entry, true);
1004
1204
 
1005
1205
  if (entry.interactiveWaitMs > 0) {
@@ -1027,10 +1227,10 @@ export async function startLightweightControllerCheck(
1027
1227
  };
1028
1228
  }
1029
1229
 
1030
- function requireEntry(repoId: string, processId: string): LightweightEntry {
1230
+ function requireEntry(scopeKey: string, processId: string): LightweightEntry {
1031
1231
  const entry = entries.get(processId);
1032
1232
  if (!entry) throw new Error(`PROCESS_NOT_FOUND: ${processId}`);
1033
- if (entry.repoId !== repoId) throw new Error(`PROCESS_REPO_MISMATCH: process ${processId} belongs to ${entry.repoId}, not ${repoId}`);
1233
+ if (entry.scopeKey !== scopeKey) throw new Error(`PROCESS_SCOPE_MISMATCH: process ${processId} belongs to ${entry.scopeKey}, not ${scopeKey}`);
1034
1234
  return entry;
1035
1235
  }
1036
1236
 
@@ -1038,17 +1238,27 @@ export function isLightweightProcessId(processId: string): boolean {
1038
1238
  return processId.startsWith('lightweight:');
1039
1239
  }
1040
1240
 
1241
+ /** Repository placement of a lightweight handle this Runtime still owns in memory. */
1242
+ export function lightweightProcessRepositoryId(processId: string): string | undefined {
1243
+ return entries.get(processId)?.repoId;
1244
+ }
1245
+
1246
+ /** Canonical Process scope key of a lightweight handle this Runtime still owns in memory. */
1247
+ export function lightweightProcessScopeKey(processId: string): string | undefined {
1248
+ return entries.get(processId)?.scopeKey;
1249
+ }
1250
+
1041
1251
  /** Test seam for proving terminal receipt recovery across Runtime-memory loss. */
1042
1252
  export function clearLightweightProcessMemoryForTest(): void {
1043
1253
  entries.clear();
1044
1254
  }
1045
1255
 
1046
- export function getLightweightProcessHandle(controllerHome: string, repoId: string, processId: string): ProcessHandle | undefined {
1256
+ export function getLightweightProcessHandle(controllerHome: string, scopeKey: string, processId: string): ProcessHandle | undefined {
1047
1257
  const entry = entries.get(processId);
1048
- if (entry?.repoId === repoId) return entryHandle(entry);
1049
- const terminal = readTerminalReceipt(controllerHome, repoId, processId);
1258
+ if (entry?.scopeKey === scopeKey) return entryHandle(entry);
1259
+ const terminal = readTerminalReceipt(controllerHome, scopeKey, processId);
1050
1260
  if (terminal) return terminal.handle;
1051
- const running = readRunningReceipt(controllerHome, repoId, processId);
1261
+ const running = readRunningReceipt(controllerHome, scopeKey, processId);
1052
1262
  if (!running) return undefined;
1053
1263
  if (running.exitObservation) {
1054
1264
  return persistRecoveredTerminalReceipt(controllerHome, running, completedObservedExitHandle(running));
@@ -1063,20 +1273,20 @@ export function getLightweightProcessHandle(controllerHome: string, repoId: stri
1063
1273
 
1064
1274
  export async function waitForLightweightProcess(
1065
1275
  controllerHome: string,
1066
- repoId: string,
1276
+ scopeKey: string,
1067
1277
  processId: string,
1068
1278
  options: WaitProcessOptions = {},
1069
1279
  ): Promise<ProcessHandle> {
1070
1280
  const entry = entries.get(processId);
1071
1281
  if (!entry) {
1072
- const terminal = readTerminalReceipt(controllerHome, repoId, processId);
1282
+ const terminal = readTerminalReceipt(controllerHome, scopeKey, processId);
1073
1283
  if (terminal) return terminal.handle;
1074
- let running = readRunningReceipt(controllerHome, repoId, processId);
1284
+ let running = readRunningReceipt(controllerHome, scopeKey, processId);
1075
1285
  if (!running) throw new Error(`PROCESS_NOT_FOUND: ${processId}`);
1076
1286
  const timeoutMs = Math.max(1, options.timeoutMs ?? 15_000);
1077
1287
  const deadline = Date.now() + timeoutMs;
1078
1288
  while (true) {
1079
- const recoveredTerminal = readTerminalReceipt(controllerHome, repoId, processId);
1289
+ const recoveredTerminal = readTerminalReceipt(controllerHome, scopeKey, processId);
1080
1290
  if (recoveredTerminal) return recoveredTerminal.handle;
1081
1291
  if (running.exitObservation) {
1082
1292
  return persistRecoveredTerminalReceipt(controllerHome, running, completedObservedExitHandle(running));
@@ -1093,10 +1303,10 @@ export async function waitForLightweightProcess(
1093
1303
  const timer = setTimeout(resolve, Math.min(50, Math.max(1, deadline - Date.now())));
1094
1304
  timer.unref?.();
1095
1305
  });
1096
- running = readRunningReceipt(controllerHome, repoId, processId) ?? running;
1306
+ running = readRunningReceipt(controllerHome, scopeKey, processId) ?? running;
1097
1307
  }
1098
1308
  }
1099
- if (entry.repoId !== repoId) throw new Error(`PROCESS_REPO_MISMATCH: process ${processId} belongs to ${entry.repoId}, not ${repoId}`);
1309
+ if (entry.scopeKey !== scopeKey) throw new Error(`PROCESS_SCOPE_MISMATCH: process ${processId} belongs to ${entry.scopeKey}, not ${scopeKey}`);
1100
1310
  if (entry.result) return entryHandle(entry);
1101
1311
  const timeoutMs = Math.max(1, options.timeoutMs ?? 15_000);
1102
1312
  await Promise.race([
@@ -1120,12 +1330,12 @@ export async function cancelAllLightweightProcesses(controllerHome: string): Pro
1120
1330
  return active.length;
1121
1331
  }
1122
1332
 
1123
- export async function cancelLightweightProcess(controllerHome: string, repoId: string, processId: string): Promise<ProcessHandle> {
1333
+ export async function cancelLightweightProcess(controllerHome: string, scopeKey: string, processId: string): Promise<ProcessHandle> {
1124
1334
  const entry = entries.get(processId);
1125
1335
  if (!entry) {
1126
- const terminal = readTerminalReceipt(controllerHome, repoId, processId);
1336
+ const terminal = readTerminalReceipt(controllerHome, scopeKey, processId);
1127
1337
  if (terminal) return terminal.handle;
1128
- const running = readRunningReceipt(controllerHome, repoId, processId);
1338
+ const running = readRunningReceipt(controllerHome, scopeKey, processId);
1129
1339
  if (!running) throw new Error(`PROCESS_NOT_FOUND: ${processId}`);
1130
1340
  if (running.exitObservation) {
1131
1341
  return persistRecoveredTerminalReceipt(controllerHome, running, completedObservedExitHandle(running));
@@ -1140,7 +1350,7 @@ export async function cancelLightweightProcess(controllerHome: string, repoId: s
1140
1350
  await terminateProcessTree(pid, { gracePeriodMs: 200, killAfterMs: 1_000, pollIntervalMs: 25 });
1141
1351
  return persistRecoveredTerminalReceipt(controllerHome, running, cancelledRecoveredHandle(running));
1142
1352
  }
1143
- if (entry.repoId !== repoId) throw new Error(`PROCESS_REPO_MISMATCH: process ${processId} belongs to ${entry.repoId}, not ${repoId}`);
1353
+ if (entry.scopeKey !== scopeKey) throw new Error(`PROCESS_SCOPE_MISMATCH: process ${processId} belongs to ${entry.scopeKey}, not ${scopeKey}`);
1144
1354
  if (!entry.result) {
1145
1355
  entry.abort.abort();
1146
1356
  await entry.promise;
@@ -1150,13 +1360,13 @@ export async function cancelLightweightProcess(controllerHome: string, repoId: s
1150
1360
 
1151
1361
  export function readLightweightProcessLogs(
1152
1362
  controllerHome: string,
1153
- repoId: string,
1363
+ scopeKey: string,
1154
1364
  processId: string,
1155
1365
  maxBytes = 32 * 1024,
1156
1366
  ): ProcessLogSlice | undefined {
1157
1367
  const entry = entries.get(processId);
1158
1368
  if (!entry) {
1159
- const terminal = readTerminalReceipt(controllerHome, repoId, processId);
1369
+ const terminal = readTerminalReceipt(controllerHome, scopeKey, processId);
1160
1370
  if (terminal) {
1161
1371
  const stdout = capProcessOutput(terminal.handle.stdout ?? '', maxBytes);
1162
1372
  const stderr = capProcessOutput(terminal.handle.stderr ?? '', maxBytes);
@@ -1170,7 +1380,7 @@ export function readLightweightProcessLogs(
1170
1380
  || Buffer.byteLength(terminal.handle.stderr ?? '', 'utf8') > maxBytes,
1171
1381
  };
1172
1382
  }
1173
- const running = readRunningReceipt(controllerHome, repoId, processId);
1383
+ const running = readRunningReceipt(controllerHome, scopeKey, processId);
1174
1384
  if (!running) return undefined;
1175
1385
  const stdout = capProcessOutput(running.handle.stdoutTail ?? '', maxBytes);
1176
1386
  const stderr = capProcessOutput(running.handle.stderrTail ?? '', maxBytes);
@@ -1184,7 +1394,7 @@ export function readLightweightProcessLogs(
1184
1394
  || Buffer.byteLength(running.handle.stderrTail ?? '', 'utf8') > maxBytes,
1185
1395
  };
1186
1396
  }
1187
- if (entry.repoId !== repoId) return undefined;
1397
+ if (entry.scopeKey !== scopeKey) return undefined;
1188
1398
  const rawStdout = entry.result?.stdout ?? entry.stdout;
1189
1399
  const rawStderr = entry.result?.stderr ?? entry.stderr;
1190
1400
  const visibleStdout = visibleOutput(rawStdout, maxBytes);