@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
@@ -8,8 +8,10 @@
8
8
  * - Durable: explicit Work/external/release boundaries only.
9
9
  */
10
10
 
11
- import type { RepositoryRecord } from '../../../cli/repositories/types';
12
- import { repositoryGitStatus } from '../../../cli/repositories/structured-git';
11
+ import {
12
+ commandExecutionScopeKey,
13
+ type RepositoryCommandScopeTarget,
14
+ } from '../../../cli/repositories/command-scope';
13
15
  import { classifyRepositoryCommand, fixedShellWrapperCommand, shellSegments, shellWordsPreservingQuotes } from '../../../cli/repositories/command-classifier';
14
16
  import {
15
17
  executeRepositoryCommandAsync,
@@ -34,15 +36,17 @@ import { DEFAULT_INTERACTIVE_WAIT_MS } from './types';
34
36
  import { durationAwareInteractiveWaitMs } from './interactive-admission';
35
37
  import { isFocusedCheckCommand } from '../thin-harness/execution-router';
36
38
  import { assertExecutionIdentity, type ResolvedExecutionIdentity } from '../../control-plane/execution/execution-identity';
37
- import { readWorkHandle, transitionWorkHandle } from '../../control-plane/execution/work-handle-store';
39
+ import { settleWorkHandleExpectedHeadAfterRepositoryCommand } from '../../control-plane/execution/work-head-settlement';
38
40
  import {
39
41
  cancelLightweightProcess,
40
42
  getLightweightProcessHandle,
41
43
  isLightweightProcessId,
44
+ lightweightProcessScopeKey,
42
45
  readLightweightProcessLogs,
43
46
  startLightweightRepositoryCommand,
44
47
  waitForLightweightProcess,
45
48
  } from './lightweight-managed';
49
+ import { isForgeInstanceProcessScopeKey, processScopeKeyForHandle } from './process-scope';
46
50
 
47
51
  export type RepositoryCommandRoute =
48
52
  | 'process_direct'
@@ -52,7 +56,8 @@ export type RepositoryCommandRoute =
52
56
 
53
57
  export interface RepositoryCommandProcessInput {
54
58
  controllerHome: string;
55
- repository: RepositoryRecord;
59
+ /** Repository identity is optional: an arbitrary workspace target carries a workspace scope key. */
60
+ repository: RepositoryCommandScopeTarget;
56
61
  command: string | readonly string[];
57
62
  cwd?: string;
58
63
  timeoutMs?: number;
@@ -65,6 +70,8 @@ export interface RepositoryCommandProcessInput {
65
70
  requestId?: string;
66
71
  workId?: string;
67
72
  commandId?: string;
73
+ /** Authenticated principal recorded with the process handle for principal-bound attachment. */
74
+ principalId?: string;
68
75
  signal?: AbortSignal;
69
76
  /** Explicit unregistered local workspace authority; never inferred from cwd. */
70
77
  allowNonGitWorkspace?: boolean;
@@ -114,77 +121,6 @@ const emptyEffects = {
114
121
  projectionUpdateCount: 0,
115
122
  };
116
123
 
117
- export type WorkHeadSettlementReason =
118
- | 'settled'
119
- | 'no_work'
120
- | 'command_not_successful'
121
- | 'work_handle_missing'
122
- | 'identity_mismatch'
123
- | 'terminal_handle'
124
- | 'branch_changed'
125
- | 'head_unavailable'
126
- | 'head_unchanged'
127
- | 'concurrent_lifecycle_write';
128
-
129
- export interface WorkHeadSettlementResult {
130
- settled: boolean;
131
- reason: WorkHeadSettlementReason;
132
- previousHead?: string;
133
- currentHead?: string;
134
- }
135
-
136
- /**
137
- * Settle the one legitimate post-command Work HEAD transition without weakening
138
- * the pre-command execution identity fence. The command has already been
139
- * admitted only if repo/checkout/branch/expectedHead matched the WorkHandle.
140
- * After success, adopt the exact current HEAD only while the same checkout and
141
- * branch still own the Work. CAS failure is a bounded no-op: finalization keeps
142
- * failing closed instead of accepting a concurrent lifecycle writer.
143
- */
144
- export function settleWorkHandleExpectedHeadAfterRepositoryCommand(input: {
145
- controllerHome: string;
146
- repository: RepositoryRecord;
147
- executionIdentity: ResolvedExecutionIdentity;
148
- workId?: string;
149
- ok?: boolean;
150
- cancelled?: boolean;
151
- timedOut?: boolean;
152
- }): WorkHeadSettlementResult {
153
- const workId = input.workId?.trim();
154
- if (!workId) return { settled: false, reason: 'no_work' };
155
- if (input.ok !== true || input.cancelled === true || input.timedOut === true) {
156
- return { settled: false, reason: 'command_not_successful' };
157
- }
158
- const handle = readWorkHandle(input.controllerHome, input.repository.repoId, workId);
159
- if (!handle) return { settled: false, reason: 'work_handle_missing' };
160
- if (
161
- handle.repositoryId !== input.executionIdentity.repositoryId
162
- || handle.checkoutId !== input.executionIdentity.checkoutId
163
- || handle.workId !== input.executionIdentity.workId
164
- ) return { settled: false, reason: 'identity_mismatch' };
165
- if (handle.state === 'merged' || handle.state === 'cleaned' || handle.state === 'failed_terminal_cleanup') {
166
- return { settled: false, reason: 'terminal_handle' };
167
- }
168
- const status = repositoryGitStatus(input.repository);
169
- if (!status.branch || status.branch !== handle.branch) {
170
- return { settled: false, reason: 'branch_changed', previousHead: handle.expectedHead, currentHead: status.head ?? undefined };
171
- }
172
- const currentHead = status.head?.trim();
173
- if (!currentHead) return { settled: false, reason: 'head_unavailable', previousHead: handle.expectedHead };
174
- if (currentHead === handle.expectedHead) {
175
- return { settled: false, reason: 'head_unchanged', previousHead: handle.expectedHead, currentHead };
176
- }
177
- try {
178
- transitionWorkHandle(input.controllerHome, handle, handle.state, { expectedHead: currentHead });
179
- return { settled: true, reason: 'settled', previousHead: handle.expectedHead, currentHead };
180
- } catch (error) {
181
- if (error instanceof Error && error.message.includes('CONTROL_PLANE_REVISION_CONFLICT')) {
182
- return { settled: false, reason: 'concurrent_lifecycle_write', previousHead: handle.expectedHead, currentHead };
183
- }
184
- throw error;
185
- }
186
- }
187
-
188
124
  const STANDALONE_RECOVERY_LIFECYCLE_COMMANDS = new Set([
189
125
  'restart-runtime',
190
126
  'bootstrap-cutover',
@@ -237,9 +173,15 @@ function repositoryCommandRecoveryLifecycle(command: string | readonly string[])
237
173
  return wrapped ? recoveryLifecycleFromShell(wrapped) : undefined;
238
174
  }
239
175
 
240
- function gitCommitWordsRequireExplicitPathScope(words: readonly string[]): boolean | undefined {
176
+ export type RepositoryGitCommitCommandScope =
177
+ | { kind: 'not_commit' }
178
+ | { kind: 'explicit_paths'; paths: string[] }
179
+ | { kind: 'staged_index' }
180
+ | { kind: 'unsafe'; reason: 'scope_widening' | 'compound_unscoped_commit' };
181
+
182
+ function gitCommitWordsScope(words: readonly string[]): RepositoryGitCommitCommandScope {
241
183
  const executable = commandBasename(words[0] ?? '');
242
- if (executable !== 'git') return undefined;
184
+ if (executable !== 'git') return { kind: 'not_commit' };
243
185
  const args = words.slice(1);
244
186
  let index = 0;
245
187
  while (index < args.length && args[index]?.startsWith('-')) {
@@ -248,29 +190,45 @@ function gitCommitWordsRequireExplicitPathScope(words: readonly string[]): boole
248
190
  else if (['--git-dir=', '--work-tree=', '--namespace='].some((prefix) => option.startsWith(prefix))) index += 1;
249
191
  else index += 1;
250
192
  }
251
- if (args[index]?.toLowerCase() !== 'commit') return undefined;
193
+ if (args[index]?.toLowerCase() !== 'commit') return { kind: 'not_commit' };
252
194
  const commitArgs = args.slice(index + 1);
253
195
  const pathSeparator = commitArgs.indexOf('--');
254
196
  const paths = pathSeparator >= 0 ? commitArgs.slice(pathSeparator + 1).filter(Boolean) : [];
255
- const widensScope = commitArgs.some((arg) => ['-a', '--all', '-i', '--include', '--interactive', '-p', '--patch'].includes(arg));
256
- return paths.length === 0 || widensScope;
197
+ const wideningFlags = ['-a', '--all', '-i', '--include', '--interactive', '-p', '--patch', '--amend', '--pathspec-from-file'];
198
+ const widensScope = commitArgs.some((arg) => wideningFlags.some((flag) => arg === flag || arg.startsWith(`${flag}=`)));
199
+ if (widensScope) return { kind: 'unsafe', reason: 'scope_widening' };
200
+ return paths.length > 0 ? { kind: 'explicit_paths', paths } : { kind: 'staged_index' };
257
201
  }
258
202
 
259
- function rawGitCommitRequiresExplicitPathScope(command: string | readonly string[]): boolean {
203
+ function aggregateShellCommitScope(shellCommand: string): RepositoryGitCommitCommandScope {
204
+ const segments = shellSegments(shellCommand);
205
+ const commits = segments
206
+ .map((segment) => gitCommitWordsScope(shellWordsPreservingQuotes(segment)))
207
+ .filter((scope) => scope.kind !== 'not_commit');
208
+ if (commits.length === 0) return { kind: 'not_commit' };
209
+ const unsafe = commits.find((scope): scope is Extract<RepositoryGitCommitCommandScope, { kind: 'unsafe' }> => scope.kind === 'unsafe');
210
+ if (unsafe) return unsafe;
211
+ if (segments.length > 1 && commits.some((scope) => scope.kind === 'staged_index')) {
212
+ return { kind: 'unsafe', reason: 'compound_unscoped_commit' };
213
+ }
214
+ const staged = commits.find((scope) => scope.kind === 'staged_index');
215
+ if (staged) return staged;
216
+ const paths = commits.flatMap((scope) => scope.kind === 'explicit_paths' ? scope.paths : []);
217
+ return { kind: 'explicit_paths', paths: [...new Set(paths)] };
218
+ }
219
+
220
+ export function classifyRawGitCommitScope(command: string | readonly string[]): RepositoryGitCommitCommandScope {
260
221
  const normalized = normalizeRepositoryCommand(command);
261
222
  if (normalized.kind === 'argv') {
262
- const direct = gitCommitWordsRequireExplicitPathScope([
223
+ const direct = gitCommitWordsScope([
263
224
  normalized.executable ?? '',
264
225
  ...(normalized.args ?? []),
265
226
  ]);
266
- if (direct !== undefined) return direct;
227
+ if (direct.kind !== 'not_commit') return direct;
267
228
  const wrapped = fixedShellWrapperCommand(normalized.value as string[]);
268
- if (!wrapped) return false;
269
- return shellSegments(wrapped)
270
- .some((segment) => gitCommitWordsRequireExplicitPathScope(shellWordsPreservingQuotes(segment)) === true);
229
+ return wrapped ? aggregateShellCommitScope(wrapped) : { kind: 'not_commit' };
271
230
  }
272
- return shellSegments(normalized.shellCommand ?? '')
273
- .some((segment) => gitCommitWordsRequireExplicitPathScope(shellWordsPreservingQuotes(segment)) === true);
231
+ return aggregateShellCommitScope(normalized.shellCommand ?? '');
274
232
  }
275
233
 
276
234
  function toProcessCommand(command: string | readonly string[], cwd: string): ProcessCommandSpec {
@@ -305,7 +263,8 @@ export function classifyRepositoryCommandRoute(
305
263
  if (repositoryCommandRecoveryLifecycle(command)) {
306
264
  return { route: 'reject', reason: 'standalone_recovery_lifecycle_required' };
307
265
  }
308
- if (rawGitCommitRequiresExplicitPathScope(command)) {
266
+ const commitScope = classifyRawGitCommitScope(command);
267
+ if (commitScope.kind === 'unsafe') {
309
268
  return { route: 'reject', reason: 'git_commit_requires_explicit_path_scope' };
310
269
  }
311
270
  if (options.forceDurable) {
@@ -402,9 +361,9 @@ export async function executeRepositoryCommandViaProcessRuntime(
402
361
  throw new Error('EXECUTION_IDENTITY_REQUIRED: repository command process path requires an immutable executionIdentity');
403
362
  }
404
363
  const executionIdentity = input.executionIdentity;
405
- if (executionIdentity.repositoryId !== input.repository.repoId) {
364
+ if (executionIdentity.repositoryId !== commandExecutionScopeKey(input.repository)) {
406
365
  throw new Error(
407
- `EXECUTION_IDENTITY_MISMATCH: repository ${input.repository.repoId} differs from identity ${executionIdentity.repositoryId}`,
366
+ `EXECUTION_IDENTITY_MISMATCH: repository ${commandExecutionScopeKey(input.repository)} differs from identity ${executionIdentity.repositoryId}`,
408
367
  );
409
368
  }
410
369
  if (executionIdentity.checkoutId !== input.repository.activeCheckoutId) {
@@ -425,13 +384,12 @@ export async function executeRepositoryCommandViaProcessRuntime(
425
384
  // immutable repository identity first, then execute through the authorized
426
385
  // non-persistent repository executor. Runtime/release durability is not a
427
386
  // command-execution tax.
428
- const canonicalCommand = normalizeRepositoryCommand(input.command);
429
387
  if (decision.route === 'process_direct') {
430
388
  assertExecutionIdentity({
431
389
  controllerHome: input.controllerHome,
432
390
  identity: executionIdentity,
433
391
  cwd,
434
- requestedRepoId: input.repository.repoId,
392
+ requestedRepoId: commandExecutionScopeKey(input.repository),
435
393
  requestedCheckoutId: input.repository.activeCheckoutId,
436
394
  });
437
395
  const directInput = {
@@ -444,8 +402,7 @@ export async function executeRepositoryCommandViaProcessRuntime(
444
402
  allowOpaqueLocalScript: decision.reason === 'lightweight_local_shell_wrapper'
445
403
  || decision.reason === 'lightweight_local_inline_interpreter',
446
404
  };
447
- const readonly = canonicalCommand.kind === 'argv'
448
- && classifyRepositoryCommand(input.command, input.repository.defaultBranch).risk === 'readonly';
405
+ const readonly = classifyRepositoryCommand(input.command, input.repository.defaultBranch).risk === 'readonly';
449
406
  if (!readonly) {
450
407
  const deferLongPreparation = decision.reason === 'ephemeral_local_build_or_test';
451
408
  const interactiveWaitMs = deferLongPreparation
@@ -468,6 +425,7 @@ export async function executeRepositoryCommandViaProcessRuntime(
468
425
  maxOutputBytes: input.maxOutputBytes,
469
426
  workId: input.workId,
470
427
  commandId: input.commandId ?? input.requestId,
428
+ ...(input.principalId ? { principalId: input.principalId } : {}),
471
429
  deferStart: deferLongPreparation,
472
430
  reuseActiveEquivalent: deferLongPreparation,
473
431
  onCompleted: (result) => {
@@ -476,7 +434,7 @@ export async function executeRepositoryCommandViaProcessRuntime(
476
434
  // evidence is unavailable. Finalization must keep failing closed until
477
435
  // a later authoritative repository inspection proves the new HEAD.
478
436
  if (result.evidenceError) return;
479
- settleWorkHandleExpectedHeadAfterRepositoryCommand({
437
+ const settlement = settleWorkHandleExpectedHeadAfterRepositoryCommand({
480
438
  controllerHome: input.controllerHome,
481
439
  repository: input.repository,
482
440
  executionIdentity,
@@ -485,6 +443,12 @@ export async function executeRepositoryCommandViaProcessRuntime(
485
443
  cancelled: result.cancelled,
486
444
  timedOut: result.timedOut,
487
445
  });
446
+ if (!settlement.settled && settlement.reason === 'concurrent_lifecycle_write') {
447
+ result.evidenceError = {
448
+ code: 'WORK_HEAD_SETTLEMENT_UNRESOLVED',
449
+ message: `Work ${input.workId ?? 'unknown'} repository command succeeded, but expectedHead settlement remained contested after bounded retry (${settlement.previousHead ?? 'unknown'} -> ${settlement.currentHead ?? 'unknown'}).`,
450
+ };
451
+ }
488
452
  },
489
453
  });
490
454
  const handle = lightweight.handle;
@@ -575,6 +539,7 @@ export async function executeRepositoryCommandViaProcessRuntime(
575
539
  repoId: executionIdentity.repositoryId,
576
540
  checkoutId: executionIdentity.checkoutId,
577
541
  executionIdentity,
542
+ ...(input.principalId ? { principalId: input.principalId } : {}),
578
543
  workId: input.workId,
579
544
  commandId: input.commandId,
580
545
  command: toProcessCommand(input.command, cwd),
@@ -612,40 +577,78 @@ export async function executeRepositoryCommandViaProcessRuntime(
612
577
  };
613
578
  }
614
579
 
615
- export function getRepositoryCommandProcess(controllerHome: string, repoId: string, processId: string): ProcessHandle | undefined {
616
- return isLightweightProcessId(processId)
617
- ? getLightweightProcessHandle(controllerHome, repoId, processId)
618
- : getProcessHandle(controllerHome, repoId, processId);
580
+ /**
581
+ * Resolve the canonical Process scope of one process handle.
582
+ *
583
+ * Explicit placement stays authoritative and is validated by the lane itself.
584
+ * When the caller omits it, this Runtime's own lightweight memory or the
585
+ * instance-level handle index supplies the recorded scope, so attachment never
586
+ * requires replaying the original placement inputs or scanning repositories.
587
+ */
588
+ function resolveCommandProcessScopeKey(
589
+ controllerHome: string,
590
+ repoId: string | undefined,
591
+ processId: string,
592
+ ): string | undefined {
593
+ const explicit = repoId?.trim();
594
+ if (explicit) return explicit;
595
+ if (isLightweightProcessId(processId)) {
596
+ const inMemory = lightweightProcessScopeKey(processId);
597
+ if (inMemory) return inMemory;
598
+ }
599
+ return processScopeKeyForHandle(controllerHome, processId);
619
600
  }
620
601
 
621
- export function waitRepositoryCommandProcess(
602
+ export function getRepositoryCommandProcess(
622
603
  controllerHome: string,
623
- repoId: string,
604
+ repoId: string | undefined,
605
+ processId: string,
606
+ ): ProcessHandle | undefined {
607
+ const scopeKey = resolveCommandProcessScopeKey(controllerHome, repoId, processId);
608
+ if (!scopeKey) return undefined;
609
+ if (!isLightweightProcessId(processId)) {
610
+ return getProcessHandle(controllerHome, scopeKey, processId);
611
+ }
612
+ return getLightweightProcessHandle(controllerHome, scopeKey, processId);
613
+ }
614
+
615
+ export async function waitRepositoryCommandProcess(
616
+ controllerHome: string,
617
+ repoId: string | undefined,
624
618
  processId: string,
625
619
  options?: Parameters<typeof waitForProcess>[3],
626
620
  ): Promise<ProcessHandle> {
627
- return isLightweightProcessId(processId)
628
- ? waitForLightweightProcess(controllerHome, repoId, processId, options)
629
- : waitForProcess(controllerHome, repoId, processId, options);
621
+ const scopeKey = resolveCommandProcessScopeKey(controllerHome, repoId, processId);
622
+ if (!scopeKey) throw new Error(`PROCESS_NOT_FOUND: ${processId}`);
623
+ if (!isLightweightProcessId(processId)) {
624
+ return waitForProcess(controllerHome, scopeKey, processId, options);
625
+ }
626
+ return waitForLightweightProcess(controllerHome, scopeKey, processId, options);
630
627
  }
631
628
 
632
- export function cancelRepositoryCommandProcess(
629
+ export async function cancelRepositoryCommandProcess(
633
630
  controllerHome: string,
634
- repoId: string,
631
+ repoId: string | undefined,
635
632
  processId: string,
636
633
  ): Promise<ProcessHandle> {
637
- return isLightweightProcessId(processId)
638
- ? cancelLightweightProcess(controllerHome, repoId, processId)
639
- : cancelProcess(controllerHome, repoId, processId);
634
+ const scopeKey = resolveCommandProcessScopeKey(controllerHome, repoId, processId);
635
+ if (!scopeKey) throw new Error(`PROCESS_NOT_FOUND: ${processId}`);
636
+ if (!isLightweightProcessId(processId)) {
637
+ return cancelProcess(controllerHome, scopeKey, processId);
638
+ }
639
+ return cancelLightweightProcess(controllerHome, scopeKey, processId);
640
640
  }
641
641
 
642
642
  export function readRepositoryCommandProcessLogs(
643
643
  controllerHome: string,
644
- repoId: string,
644
+ repoId: string | undefined,
645
645
  processId: string,
646
646
  maxBytes?: number,
647
647
  ) {
648
- return isLightweightProcessId(processId)
649
- ? readLightweightProcessLogs(controllerHome, repoId, processId, maxBytes)
650
- : readProcessLogs(controllerHome, repoId, processId, maxBytes);
648
+ const scopeKey = resolveCommandProcessScopeKey(controllerHome, repoId, processId);
649
+ if (!scopeKey) return undefined;
650
+ if (!isLightweightProcessId(processId)) {
651
+ return readProcessLogs(controllerHome, scopeKey, processId, maxBytes);
652
+ }
653
+ return readLightweightProcessLogs(controllerHome, scopeKey, processId, maxBytes);
651
654
  }
@@ -9,8 +9,9 @@
9
9
  import { existsSync, readFileSync, readdirSync, unlinkSync, statSync } from 'fs';
10
10
  import { join } from 'path';
11
11
  import { ensureRepositoryControllerLayout, repositoryControllerRoot } from '../../../cli/repositories/controller-home';
12
+ import { isRepositoryProcessScopeKey, processScopeRoot } from './process-scope';
12
13
  import { getProcessRecord, listActiveProcessIds } from './store';
13
- import { reconcileStaleManagedProcessForMaintenance } from './runtime';
14
+ import { reconcileStaleManagedProcessForMaintenance, releaseProcessLeasesOnce } from './runtime';
14
15
  import { isManagedProcessActive, type ProcessRuntimeStatus } from './types';
15
16
  import { assertRuntimeMayWrite } from '../../root/write-fence';
16
17
  import { isProcessAlive } from '../../shared/process-tree';
@@ -52,7 +53,12 @@ export interface ProcessGcResult {
52
53
  }
53
54
 
54
55
  function processesDir(controllerHome: string, repoId: string): string {
55
- return join(ensureRepositoryControllerLayout(controllerHome, repoId), 'processes');
56
+ // Repository scopes keep their per-repository layout; instance and workspace
57
+ // scopes own sibling partitions so their process records are still collected.
58
+ const root = isRepositoryProcessScopeKey(repoId)
59
+ ? ensureRepositoryControllerLayout(controllerHome, repoId)
60
+ : processScopeRoot(controllerHome, repoId);
61
+ return join(root, 'processes');
56
62
  }
57
63
 
58
64
  function logDir(controllerHome: string, repoId: string): string {
@@ -196,6 +202,13 @@ export function gcTerminalProcesses(options: ProcessGcOptions): ProcessGcResult
196
202
  }
197
203
  }
198
204
  if (!TERMINAL.has(metadata.status)) continue;
205
+ // Terminal evidence and lease cleanup are separate durable phases. A
206
+ // crash/fence between them must not leave a workspace lease immortal just
207
+ // because the terminal record is still inside the retention window.
208
+ const terminalRecord = getProcessRecord(options.controllerHome, options.repoId, processId);
209
+ if (terminalRecord?.terminalWritten === true && terminalRecord.leasesReleased !== true) {
210
+ releaseProcessLeasesOnce(options.controllerHome, options.repoId, processId);
211
+ }
199
212
  // Do not delete terminal evidence that has never been read when maxAge is not exceeded
200
213
  // unless we are strictly over maxTerminalRecords budget (handled by sort below).
201
214
  const finished = Date.parse(metadata.finishedAt ?? metadata.updatedAt ?? '');
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Instance-level Process handle index.
3
+ *
4
+ * Process attachment (get/wait/logs/cancel) resolves the concrete execution
5
+ * target from the returned handle identity instead of replaying the original
6
+ * placement inputs or scanning every repository partition. The index lives in
7
+ * Controller Home, so it is a ForgeInstance-level locator: repository/checkout
8
+ * placement is target metadata, never the address space of the process itself.
9
+ *
10
+ * This is a rebuildable locator projection. The Process Runtime record and its
11
+ * exit receipt remain the only outcome evidence; a missing or stale index entry
12
+ * degrades attachment convenience and never becomes a capability gate.
13
+ */
14
+
15
+ import { readForgeInstanceIdentity } from '../../../../packages/kernel/identity/api/index';
16
+ import { mutateControlPlaneRecord, readControlPlaneRecord } from '../../control-plane/persistence/sqlite-store';
17
+
18
+ export const PROCESS_HANDLE_INDEX_NAMESPACE = 'process_handle_index';
19
+ const PROCESS_HANDLE_INDEX_SCOPE = 'instance';
20
+ const PROCESS_HANDLE_INDEX_SCHEMA_VERSION = 1;
21
+
22
+ export type ProcessExecutionTargetScope = 'forge_instance' | 'repository' | 'workspace';
23
+
24
+ /** Typed execution target for one process handle. Repository placement is optional context. */
25
+ export interface ProcessExecutionTarget {
26
+ schemaVersion: 1;
27
+ scope: ProcessExecutionTargetScope;
28
+ forgeInstanceId?: string;
29
+ repositoryId?: string;
30
+ /** Workspace scope id when the target is an arbitrary workspace without repository semantics. */
31
+ workspaceId?: string;
32
+ checkoutId?: string;
33
+ }
34
+
35
+ export interface ProcessHandleIndexEntry {
36
+ schemaVersion: 1;
37
+ processId: string;
38
+ lane: 'lightweight' | 'managed';
39
+ target: ProcessExecutionTarget;
40
+ /** Authenticated principal that owns the handle; opaque ids never authorize by themselves. */
41
+ principalId?: string;
42
+ workId?: string;
43
+ commandId?: string;
44
+ recordedAt: string;
45
+ updatedAt: string;
46
+ }
47
+
48
+ function boundedId(value: string | undefined): string | undefined {
49
+ const normalized = value?.trim();
50
+ return normalized ? normalized.slice(0, 512) : undefined;
51
+ }
52
+
53
+ export function forgeInstanceIdFor(controllerHome: string): string | undefined {
54
+ return readForgeInstanceIdentity(controllerHome)?.instanceId;
55
+ }
56
+
57
+ export function forgeInstanceExecutionTarget(controllerHome: string): ProcessExecutionTarget {
58
+ const forgeInstanceId = forgeInstanceIdFor(controllerHome);
59
+ return { schemaVersion: 1, scope: 'forge_instance', ...(forgeInstanceId ? { forgeInstanceId } : {}) };
60
+ }
61
+
62
+ export function repositoryExecutionTarget(
63
+ controllerHome: string,
64
+ repositoryId: string,
65
+ checkoutId?: string,
66
+ ): ProcessExecutionTarget {
67
+ const forgeInstanceId = forgeInstanceIdFor(controllerHome);
68
+ const repository = boundedId(repositoryId);
69
+ if (!repository) throw new Error('PROCESS_EXECUTION_TARGET_REPOSITORY_REQUIRED');
70
+ const checkout = boundedId(checkoutId);
71
+ return {
72
+ schemaVersion: 1,
73
+ scope: 'repository',
74
+ ...(forgeInstanceId ? { forgeInstanceId } : {}),
75
+ repositoryId: repository,
76
+ ...(checkout ? { checkoutId: checkout } : {}),
77
+ };
78
+ }
79
+
80
+ /** Target for an arbitrary workspace: no repository identity is created or implied. */
81
+ export function workspaceExecutionTarget(controllerHome: string, workspaceId: string): ProcessExecutionTarget {
82
+ const workspace = boundedId(workspaceId);
83
+ if (!workspace) throw new Error('PROCESS_EXECUTION_TARGET_WORKSPACE_REQUIRED');
84
+ const forgeInstanceId = forgeInstanceIdFor(controllerHome);
85
+ return {
86
+ schemaVersion: 1,
87
+ scope: 'workspace',
88
+ ...(forgeInstanceId ? { forgeInstanceId } : {}),
89
+ workspaceId: workspace,
90
+ };
91
+ }
92
+
93
+ export function recordProcessHandleIndexEntry(
94
+ controllerHome: string,
95
+ input: Omit<ProcessHandleIndexEntry, 'schemaVersion' | 'recordedAt' | 'updatedAt'> & { now?: string },
96
+ ): ProcessHandleIndexEntry | undefined {
97
+ const processId = boundedId(input.processId);
98
+ if (!processId) return undefined;
99
+ const now = input.now ?? new Date().toISOString();
100
+ const principalId = boundedId(input.principalId);
101
+ const workId = boundedId(input.workId);
102
+ const commandId = boundedId(input.commandId);
103
+ try {
104
+ const record = mutateControlPlaneRecord<ProcessHandleIndexEntry>(controllerHome, {
105
+ namespace: PROCESS_HANDLE_INDEX_NAMESPACE,
106
+ scope: PROCESS_HANDLE_INDEX_SCOPE,
107
+ key: processId,
108
+ schemaVersion: PROCESS_HANDLE_INDEX_SCHEMA_VERSION,
109
+ action: 'process_handle_index_record',
110
+ mutate: (current) => ({
111
+ schemaVersion: PROCESS_HANDLE_INDEX_SCHEMA_VERSION,
112
+ processId,
113
+ lane: input.lane,
114
+ target: input.target,
115
+ ...(principalId ? { principalId } : {}),
116
+ ...(current?.value.principalId && !principalId ? { principalId: current.value.principalId } : {}),
117
+ ...(workId ? { workId } : {}),
118
+ ...(commandId ? { commandId } : {}),
119
+ recordedAt: current?.value.recordedAt ?? now,
120
+ updatedAt: now,
121
+ }),
122
+ });
123
+ return record.value;
124
+ } catch {
125
+ // A locator projection must never block an already-authorized process.
126
+ return undefined;
127
+ }
128
+ }
129
+
130
+ export function readProcessHandleIndexEntry(
131
+ controllerHome: string,
132
+ processId: string,
133
+ ): ProcessHandleIndexEntry | undefined {
134
+ const key = boundedId(processId);
135
+ if (!key) return undefined;
136
+ try {
137
+ const record = readControlPlaneRecord<ProcessHandleIndexEntry>(
138
+ controllerHome,
139
+ PROCESS_HANDLE_INDEX_NAMESPACE,
140
+ PROCESS_HANDLE_INDEX_SCOPE,
141
+ key,
142
+ );
143
+ const value = record?.value;
144
+ if (!value || value.schemaVersion !== PROCESS_HANDLE_INDEX_SCHEMA_VERSION || value.processId !== key) return undefined;
145
+ if (!value.target || value.target.schemaVersion !== 1) return undefined;
146
+ return value;
147
+ } catch {
148
+ return undefined;
149
+ }
150
+ }
151
+
152
+ /** Resolve the concrete execution target recorded for one process handle. */
153
+ export function resolveProcessExecutionTarget(
154
+ controllerHome: string,
155
+ processId: string,
156
+ ): ProcessExecutionTarget | undefined {
157
+ return readProcessHandleIndexEntry(controllerHome, processId)?.target;
158
+ }
159
+
160
+ /**
161
+ * Principal that owns one process handle, when recorded. Opaque handle ids
162
+ * locate a record; they never authorize attachment on their own.
163
+ */
164
+ export function processHandlePrincipalId(controllerHome: string, processId: string): string | undefined {
165
+ return readProcessHandleIndexEntry(controllerHome, processId)?.principalId;
166
+ }
167
+
168
+ /** Compatibility narrowing: the repository placement recorded for a process, when it has one. */
169
+ export function resolveProcessRepositoryTarget(
170
+ controllerHome: string,
171
+ processId: string,
172
+ ): { repositoryId: string; checkoutId?: string } | undefined {
173
+ const target = resolveProcessExecutionTarget(controllerHome, processId);
174
+ if (!target?.repositoryId) return undefined;
175
+ return { repositoryId: target.repositoryId, ...(target.checkoutId ? { checkoutId: target.checkoutId } : {}) };
176
+ }