@moretea-labs/forge 1.8.0 → 1.8.2

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 (695) hide show
  1. package/AGENTS.md +73 -7
  2. package/CHANGELOG.md +34 -0
  3. package/CLAUDE.md +17 -2
  4. package/CONTRIBUTING.md +3 -2
  5. package/README.en.md +24 -3
  6. package/README.md +10 -6
  7. package/README.zh-CN.md +5 -3
  8. package/THIRD_PARTY_NOTICES.md +1 -2
  9. package/adapters/chatgpt/browser-delivery-host.ts +7 -1
  10. package/adapters/chatgpt/browser-delivery-runtime.ts +531 -56
  11. package/adapters/chatgpt/controller-binding-store.ts +101 -22
  12. package/adapters/chatgpt/controller-round-host.ts +15 -25
  13. package/adapters/chatgpt/controller-round-settlement-store.ts +58 -4
  14. package/adapters/chatgpt/provider-delivery.ts +229 -2
  15. package/adapters/chatgpt/work-conversation-binding-store.ts +99 -54
  16. package/adapters/computer/chatgpt-extension-target.ts +708 -0
  17. package/adapters/computer/chrome-extension/background.js +541 -0
  18. package/adapters/computer/chrome-extension/content.js +402 -0
  19. package/adapters/computer/chrome-extension/core.js +24 -0
  20. package/adapters/computer/chrome-extension/manifest.json +32 -0
  21. package/adapters/computer/desktop-operator-discovery.ts +11 -31
  22. package/adapters/computer/desktop-operator-provider.ts +18 -6
  23. package/adapters/computer/interaction-target-authority.ts +178 -24
  24. package/adapters/mcp/access-mode.ts +18 -39
  25. package/adapters/mcp/auth.ts +2 -7
  26. package/adapters/mcp/instructions.ts +6 -5
  27. package/adapters/mcp/multi-repository.ts +10 -47
  28. package/adapters/mcp/oauth.ts +73 -0
  29. package/adapters/mcp/paths.ts +4 -1
  30. package/adapters/mcp/runtime-gateway/bounded-result-runtime.ts +62 -0
  31. package/adapters/mcp/runtime-gateway/cognition-settlement.ts +201 -0
  32. package/adapters/mcp/runtime-gateway/context-adapter.ts +490 -113
  33. package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +83 -0
  34. package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +20 -5
  35. package/adapters/mcp/runtime-gateway/core-capability-adapter.ts +258 -0
  36. package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +10 -27
  37. package/adapters/mcp/runtime-gateway/engineering-tool-contract.ts +15 -0
  38. package/adapters/mcp/runtime-gateway/execution-tools.ts +14 -54
  39. package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +2 -1
  40. package/adapters/mcp/runtime-gateway/plugin-adapter.ts +132 -47
  41. package/adapters/mcp/runtime-gateway/process-tools.ts +173 -23
  42. package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +16 -4
  43. package/adapters/mcp/runtime-gateway/recovery-adapter.ts +69 -52
  44. package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +4 -35
  45. package/adapters/mcp/runtime-gateway/result-adapter.ts +10 -4
  46. package/adapters/mcp/runtime-gateway/router.ts +19 -507
  47. package/adapters/mcp/runtime-gateway/routing-policy.ts +506 -0
  48. package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +15 -66
  49. package/adapters/mcp/runtime-gateway/runtime-readiness-observation.ts +218 -0
  50. package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +123 -178
  51. package/adapters/mcp/runtime-gateway/runtime-tools.ts +11 -5
  52. package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +37 -1
  53. package/adapters/mcp/runtime-gateway/shared-adapter.ts +20 -0
  54. package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +416 -270
  55. package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +140 -0
  56. package/adapters/mcp/runtime-gateway/work-adapter.ts +262 -3123
  57. package/adapters/mcp/runtime-gateway/work-controller-operations.ts +257 -0
  58. package/adapters/mcp/runtime-gateway/work-detail-projection.ts +60 -0
  59. package/adapters/mcp/runtime-gateway/work-input-wire-migration.ts +229 -0
  60. package/adapters/mcp/runtime-gateway/work-learning-operations.ts +145 -0
  61. package/adapters/mcp/runtime-gateway/work-list-projection.ts +38 -0
  62. package/adapters/mcp/runtime-gateway/work-plan-operations.ts +382 -0
  63. package/adapters/mcp/runtime-gateway/work-repair-adapter.ts +308 -0
  64. package/adapters/mcp/runtime-gateway/work-requirement-operations.ts +148 -0
  65. package/adapters/mcp/runtime-gateway/work-semantic-operations.ts +320 -0
  66. package/adapters/mcp/runtime-gateway/work-workflow-operations.ts +113 -0
  67. package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +180 -0
  68. package/adapters/mcp/server.ts +91 -26
  69. package/adapters/mcp/setup.ts +5 -13
  70. package/adapters/mcp/tool-mapping/access-tools.ts +0 -6
  71. package/adapters/mcp/tool-mapping/legacy-tool-service.ts +703 -3092
  72. package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +5 -10
  73. package/adapters/mcp/tool-mapping/repository-tools.ts +170 -213
  74. package/adapters/mcp/toolset-names.ts +11 -37
  75. package/adapters/mcp/toolset.ts +19 -92
  76. package/{src/cli → adapters}/mcp/transports/AGENTS.md +5 -5
  77. package/{src/cli → adapters}/mcp/transports/CLAUDE.md +5 -5
  78. package/adapters/mcp/transports/http-observation.ts +377 -0
  79. package/adapters/mcp/transports/http-post-lifecycle.ts +19 -0
  80. package/adapters/mcp/transports/http.ts +200 -683
  81. package/adapters/mcp/transports/oauth-http.ts +322 -0
  82. package/adapters/mcp/transports/session-registry.ts +6 -0
  83. package/adapters/mcp/tunnels/openai-secure-tunnel.ts +89 -5
  84. package/adapters/mcp/types.ts +0 -6
  85. package/assets/hooks/lib/session-state.sh +0 -38
  86. package/assets/hooks/post-bash.sh +1 -1
  87. package/assets/hooks/post-tool-observer.sh +0 -5
  88. package/assets/hooks/prompt-guard.sh +0 -55
  89. package/assets/partials/04-project-structure.partial.md +1 -1
  90. package/assets/partials/07-footer.partial.md +1 -1
  91. package/assets/partials-agents/02-operating-mode.partial.md +1 -1
  92. package/assets/partials-agents/08-deep-docs.partial.md +1 -1
  93. package/assets/plugin-registry.v1.json +6 -4
  94. package/assets/reference-configs/agentic-development-flow.md +26 -1
  95. package/assets/reference-configs/external-tooling.md +0 -76
  96. package/assets/reference-configs/global-working-rules.md +19 -0
  97. package/assets/reference-configs/release-deploy.md +1 -1
  98. package/assets/templates/helpers/architecture-queue.sh +1 -1
  99. package/assets/templates/helpers/check-agent-tooling.sh +1 -327
  100. package/assets/templates/helpers/check-task-workflow.sh +1 -1
  101. package/assets/templates/helpers/ensure-task-workflow.sh +0 -14
  102. package/assets/templates/helpers/migrate-project-template.sh +2 -2
  103. package/assets/workflow-contract.v1.json +0 -2
  104. package/docs/README.md +5 -2
  105. package/docs/architecture/CURRENT.md +205 -51
  106. package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +14 -5
  107. package/docs/architecture/decisions/20260823-immediate-controller-relay.md +6 -3
  108. package/docs/architecture/decisions/20260904-ios-device-migration-baseline.md +42 -0
  109. package/docs/architecture/decisions/20260907-assistant-learning-loop.md +2 -0
  110. package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +19 -4
  111. package/docs/architecture/decisions/20260916-workflow-supervisor-authority.md +249 -0
  112. package/docs/architecture/decisions/20260917-cognitive-memory-foundation.md +82 -0
  113. package/docs/architecture/decisions/20260918-stable-candidate-release-lifecycle.md +234 -0
  114. package/docs/architecture/decisions/20260919-autonomous-work-liveness.md +62 -0
  115. package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +74 -0
  116. package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +342 -0
  117. package/docs/architecture/decisions/20261005-forge-v3-desktop-client-boundary.md +77 -0
  118. package/docs/architecture/decisions/20261009-exact-code-context-discovery.md +19 -0
  119. package/docs/architecture/decisions/20261009-generated-xcode-cache-retention.md +37 -0
  120. package/docs/architecture/decisions/20261011-autonomous-continuation-convergence.md +597 -0
  121. package/docs/architecture/decisions/20261017-edit-session-finalization-reconciliation.md +17 -0
  122. package/docs/architecture/decisions/20261019-retire-host-skills.md +16 -0
  123. package/docs/architecture/diagrams/agentic-dev-plugin-architecture.html +1 -1
  124. package/docs/architecture/domains/public-surface.md +3 -5
  125. package/docs/architecture/domains/verification.md +6 -5
  126. package/docs/architecture/domains/workflow-engine.md +6 -0
  127. package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +3 -3
  128. package/docs/architecture/requests/2026-09-04-computer-plugin-workflow-taxonomy.md +4 -4
  129. package/docs/architecture/reviews/20261015-code-search-runtime-acceptance.md +75 -0
  130. package/docs/forge-plugin-management.md +16 -4
  131. package/docs/operations/controller-browser-plugin.md +23 -0
  132. package/docs/operations/controller-performance-and-502.md +17 -0
  133. package/docs/operations/controller-reliability-runbook.md +2 -2
  134. package/docs/operations/features.md +6 -7
  135. package/docs/operations/features.zh-CN.md +1 -1
  136. package/docs/operations/github-repository.md +4 -4
  137. package/docs/operations/github-semantic-release-projection.md +20 -0
  138. package/docs/operations/homebrew.md +2 -2
  139. package/docs/operations/mcp-tool-exposure.md +13 -52
  140. package/docs/operations/releasing.md +2 -0
  141. package/docs/operations/runtime-performance-diagnostics.md +8 -0
  142. package/docs/operations/standalone-disaster-recovery.md +15 -7
  143. package/docs/tutorials/01-install-and-start.zh-CN.md +1 -1
  144. package/docs/tutorials/03-first-repository-task.md +2 -0
  145. package/docs/wiki/Computer-and-Plugins.md +78 -0
  146. package/docs/wiki/Computer-and-Plugins.zh-CN.md +88 -0
  147. package/docs/wiki/Home.md +16 -2
  148. package/docs/wiki/Implementation.md +25 -13
  149. package/docs/wiki/Installation.md +28 -32
  150. package/docs/wiki/Integrations.md +4 -0
  151. package/docs/wiki/Quick-Start.md +35 -22
  152. package/docs/wiki/Releases-and-Upgrades.md +15 -25
  153. package/docs/wiki/_Sidebar.md +5 -1
  154. package/package.json +25 -25
  155. package/packages/kernel/cognition/api/index.ts +6 -0
  156. package/packages/kernel/cognition/application/activation-service.ts +451 -0
  157. package/packages/kernel/cognition/application/consolidation-service.ts +185 -0
  158. package/packages/kernel/cognition/application/legacy-experience-adapter.ts +38 -0
  159. package/packages/kernel/cognition/application/memory-service.ts +64 -0
  160. package/packages/kernel/cognition/domain/learning.ts +106 -0
  161. package/packages/kernel/cognition/domain/memory.ts +254 -0
  162. package/packages/kernel/controller/api/index.ts +1 -0
  163. package/packages/kernel/controller/application/continuation-service.ts +281 -0
  164. package/packages/kernel/controller/application/controller-round-service.ts +12 -0
  165. package/packages/kernel/controller/domain/controller-round-transition-policy.ts +242 -21
  166. package/packages/kernel/controller/domain/controller-round.ts +4 -1
  167. package/packages/kernel/controller/domain/execution-quality.ts +3 -1
  168. package/packages/kernel/controller/infrastructure/controller-round-store.ts +689 -103
  169. package/packages/kernel/controller/infrastructure/controller-session-store.ts +348 -97
  170. package/packages/kernel/controller/ports/controller-host.ts +2 -0
  171. package/packages/kernel/identity/api/index.ts +10 -0
  172. package/packages/kernel/identity/domain/activity-projection.ts +43 -0
  173. package/packages/kernel/identity/domain/capability-broker.ts +60 -0
  174. package/packages/kernel/identity/domain/grant.ts +72 -0
  175. package/packages/kernel/identity/domain/owned-resource.ts +116 -0
  176. package/packages/kernel/identity/domain/user-request.ts +93 -0
  177. package/packages/kernel/identity/infrastructure/activity-projection-store.ts +87 -0
  178. package/packages/kernel/identity/infrastructure/capability-broker.ts +81 -0
  179. package/packages/kernel/identity/infrastructure/grant-store.ts +284 -0
  180. package/packages/kernel/identity/infrastructure/owned-resource-store.ts +259 -0
  181. package/packages/kernel/identity/infrastructure/user-request-store.ts +182 -0
  182. package/packages/kernel/scheduler/api/index.ts +0 -2
  183. package/packages/kernel/scheduler/application/eligibility.ts +4 -1
  184. package/packages/kernel/scheduler/application/schedule-service.ts +3 -0
  185. package/packages/kernel/scheduler/application/settlement.ts +0 -15
  186. package/packages/kernel/scheduler/domain/schedule.ts +87 -0
  187. package/packages/kernel/scheduler/infrastructure/schedule-store.ts +166 -143
  188. package/packages/kernel/work/api/index.ts +3 -2
  189. package/packages/kernel/work/application/work-service.ts +18 -42
  190. package/packages/kernel/work/domain/current-task-lineage.ts +104 -0
  191. package/packages/kernel/work/domain/engineering-design.ts +10 -5
  192. package/packages/kernel/work/domain/engineering-profile.ts +8 -12
  193. package/packages/kernel/work/domain/evaluation-promotion-receipt.ts +186 -0
  194. package/packages/kernel/work/domain/execution-concurrency.ts +19 -26
  195. package/packages/kernel/work/domain/execution-snapshot.ts +0 -31
  196. package/packages/kernel/work/domain/implementation-review.ts +14 -331
  197. package/packages/kernel/work/domain/objective-graph.ts +119 -0
  198. package/packages/kernel/work/domain/project-engineering-contract.ts +23 -1
  199. package/packages/kernel/work/domain/repository-completion-receipt.ts +1 -1
  200. package/packages/kernel/work/domain/state-machine.ts +34 -65
  201. package/packages/kernel/work/domain/types.ts +57 -51
  202. package/packages/kernel/work/infrastructure/work-contract-store.ts +847 -729
  203. package/packages/kernel/work/ports/work-contract-store.ts +5 -2
  204. package/packages/plugin-runtime/browser/provider-registry.ts +12 -36
  205. package/packages/plugin-runtime/browser/session-authority.ts +2 -1
  206. package/packages/plugin-runtime/computer/chatgpt-identity.ts +24 -0
  207. package/packages/plugin-runtime/computer/conversation-target.ts +153 -0
  208. package/packages/plugin-runtime/computer/index.ts +2 -0
  209. package/packages/plugin-runtime/computer/target-authority.ts +26 -1
  210. package/packages/plugin-runtime/external/unix-jsonl-transport.ts +142 -18
  211. package/packages/protocols/computer/contract.ts +27 -1
  212. package/scripts/activate-source-baseline.ts +7 -9
  213. package/scripts/assemble-template.ts +11 -72
  214. package/scripts/canary-controller-semantic-wait.ts +12 -24
  215. package/scripts/check-mcp-compatibility.ts +94 -201
  216. package/scripts/check-package-identity.mjs +0 -5
  217. package/scripts/check-runtime-architecture.mjs +921 -239
  218. package/scripts/forge-local-recovery-helper.mjs +93 -15
  219. package/scripts/init-project.sh +0 -46
  220. package/scripts/install-ios-hid-toolchain.sh +60 -0
  221. package/scripts/install-standalone-recovery.ts +1 -1
  222. package/scripts/lib/project-init-lib.sh +6 -3
  223. package/scripts/migrate-windows-wsl-controller-home.ts +2 -0
  224. package/scripts/open-source-audit-allowlist.txt +1 -3
  225. package/scripts/run-bounded-command.mjs +5 -0
  226. package/scripts/run-governed-gate.ts +2 -1
  227. package/scripts/run-mobile-monitor-bridge.ts +0 -1
  228. package/scripts/smoke-control-plane-failure-domain.ts +94 -0
  229. package/scripts/smoke-ios-physical-device.ts +38 -10
  230. package/scripts/smoke-mcp-http-runtime.ts +12 -8
  231. package/scripts/smoke-mcp-tool-surface.ts +27 -41
  232. package/scripts/smoke-runtime-recovery.ts +12 -43
  233. package/scripts/smoke-schedule-engine.ts +23 -15
  234. package/scripts/smoke-unattended-transport-recovery.ts +223 -0
  235. package/scripts/smoke-user-request-continuation-restart.ts +232 -0
  236. package/scripts/smoke-workflow-supervisor-chrome-adapter.ts +95 -0
  237. package/scripts/smoke-workflow-supervisor-process-restart.ts +276 -0
  238. package/scripts/smoke-workflow-supervisor-restart-recovery.ts +150 -0
  239. package/scripts/smoke-workflow-supervisor.ts +103 -0
  240. package/scripts/sync-generated-authority.mjs +0 -1
  241. package/scripts/verify-forge-runtime.sh +2 -1
  242. package/src/cli/agent-jobs/executor-health.ts +12 -35
  243. package/src/cli/agent-jobs/integration.ts +20 -51
  244. package/src/cli/agent-jobs/job-manager.ts +7 -3
  245. package/src/cli/chatgpt-browser/file-policy.ts +2 -2
  246. package/src/cli/commands/brain-assistant.ts +27 -13
  247. package/src/cli/commands/brain.ts +13 -15
  248. package/src/cli/commands/chatgpt.ts +1 -163
  249. package/src/cli/commands/doctor.ts +1 -143
  250. package/src/cli/commands/global-runtime.ts +3 -196
  251. package/src/cli/commands/init-hook.ts +6 -23
  252. package/src/cli/commands/init.ts +3 -252
  253. package/src/cli/commands/mcp.ts +0 -5
  254. package/src/cli/commands/prompt-guard-decision.ts +0 -2
  255. package/src/cli/commands/recovery.ts +137 -135
  256. package/src/cli/commands/repository.ts +17 -1
  257. package/src/cli/commands/runtime.ts +3 -3
  258. package/src/cli/commands/setup-execution.ts +41 -0
  259. package/src/cli/commands/setup-profile.ts +8 -0
  260. package/src/cli/controller/check-runner.ts +13 -2
  261. package/src/cli/controller/completion-backlog.ts +3 -3
  262. package/src/cli/controller/completion-orchestrator.ts +5 -44
  263. package/src/cli/controller/completion-target.ts +3 -72
  264. package/src/cli/controller/composite-operations.ts +1 -1
  265. package/src/cli/controller/context/instruction-context.ts +1 -1
  266. package/src/cli/controller/context/known-paths.ts +2 -2
  267. package/src/cli/controller/context/query-planning.ts +11 -4
  268. package/src/cli/controller/context/rule-resolution.ts +2 -2
  269. package/src/cli/controller/context/source-materializer.ts +83 -102
  270. package/src/cli/controller/context/structural-provider.ts +84 -0
  271. package/src/cli/controller/context/structural.ts +6 -6
  272. package/src/cli/controller/context/types.ts +8 -9
  273. package/src/cli/controller/context-pack.ts +107 -84
  274. package/src/cli/controller/execution-completion.ts +4 -7
  275. package/src/cli/controller/execution-policy.ts +36 -153
  276. package/src/cli/controller/governance.ts +2 -3
  277. package/src/cli/controller/issue-store.ts +4 -99
  278. package/src/cli/controller/launch-agents.ts +59 -18
  279. package/src/cli/controller/operational-plan.ts +25 -52
  280. package/src/cli/controller/runtime-config.ts +5 -1
  281. package/src/cli/controller/stuck-state-migration.ts +2 -3
  282. package/src/cli/controller/systemd-user.ts +42 -10
  283. package/src/cli/editing/edit-session.ts +18 -12
  284. package/src/cli/github/github.ts +4 -4
  285. package/src/cli/github/semantic-projection.ts +174 -0
  286. package/src/cli/hook/prompt-intents.ts +0 -9
  287. package/src/cli/index.ts +1 -43
  288. package/src/cli/local-bridge/connector-freshness.ts +1 -12
  289. package/src/cli/local-bridge/console-automations.ts +19 -14
  290. package/src/cli/local-bridge/console-view-models.ts +4 -13
  291. package/src/cli/local-bridge/facade-api.ts +64 -193
  292. package/src/cli/local-bridge/server.ts +24 -147
  293. package/src/cli/local-bridge/types.ts +0 -1
  294. package/src/cli/mcp/oauth-client-retirement.ts +74 -0
  295. package/src/cli/repositories/command-classifier.ts +0 -9
  296. package/src/cli/repositories/command-executor.ts +29 -23
  297. package/src/cli/repositories/command-scope.ts +37 -18
  298. package/src/cli/repositories/controller-home.ts +48 -0
  299. package/src/cli/repositories/ephemeral-workspace.ts +20 -30
  300. package/src/cli/repositories/git-command-executor.ts +2 -2
  301. package/src/cli/repositories/locks.ts +20 -0
  302. package/src/cli/repositories/registry.ts +79 -12
  303. package/src/cli/repositories/safe-patch.ts +2 -12
  304. package/src/cli/repositories/structured-git.ts +101 -5
  305. package/src/cli/repository/inspector.ts +185 -343
  306. package/src/cli/repository/session-cache.ts +92 -6
  307. package/src/effects/process-runner.ts +17 -1
  308. package/src/runtime/context/assistant-context.ts +20 -7
  309. package/src/runtime/context/assistant-work-context.ts +89 -27
  310. package/src/runtime/context/automatic-learning.ts +565 -0
  311. package/src/runtime/context/cognitive-attention.ts +173 -0
  312. package/src/runtime/context/cognitive-skill-canary.ts +158 -0
  313. package/src/runtime/context/context-closure.ts +46 -9
  314. package/src/runtime/context/context-pack-process.ts +103 -0
  315. package/src/runtime/context/context-plane.ts +1 -9
  316. package/src/runtime/context/direct-controller-learning.ts +298 -0
  317. package/src/runtime/context/generic-lsp-provider.ts +1 -1
  318. package/src/runtime/context/semantic-navigation-contract.ts +16 -0
  319. package/src/runtime/context/semantic-navigation.ts +7 -35
  320. package/src/runtime/context/typescript-navigation-process.ts +145 -0
  321. package/src/runtime/context/typescript-navigation.ts +89 -3
  322. package/src/runtime/control-plane/cleanup-artifact-retention.ts +215 -12
  323. package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +9 -47
  324. package/src/runtime/control-plane/execution/controller-authority-recovery.ts +34 -4
  325. package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +29 -20
  326. package/src/runtime/control-plane/execution/execution-identity.ts +23 -3
  327. package/src/runtime/control-plane/execution/repository-work-attribution.ts +7 -30
  328. package/src/runtime/control-plane/execution/retained-work-resume.ts +206 -199
  329. package/src/runtime/control-plane/execution/session-store.ts +31 -1
  330. package/src/runtime/control-plane/execution/validation.ts +6 -8
  331. package/src/runtime/control-plane/execution/work-authority-reconciler.ts +13 -42
  332. package/src/runtime/control-plane/execution/work-check-evidence.ts +137 -0
  333. package/src/runtime/control-plane/execution/work-completion-authority.ts +30 -85
  334. package/src/runtime/control-plane/execution/work-delivery-service.ts +616 -0
  335. package/src/runtime/control-plane/execution/work-evidence-policy.ts +12 -50
  336. package/src/runtime/control-plane/execution/work-execution-support.ts +50 -149
  337. package/src/runtime/control-plane/execution/work-handle-authority.ts +197 -110
  338. package/src/runtime/control-plane/execution/work-handle-store.ts +72 -44
  339. package/src/runtime/control-plane/execution/work-head-settlement.ts +53 -20
  340. package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +52 -29
  341. package/src/runtime/control-plane/execution/work-operation-service.ts +60 -34
  342. package/src/runtime/control-plane/execution/work-preparation-service.ts +231 -267
  343. package/src/runtime/control-plane/execution/work-process-evidence.ts +2 -2
  344. package/src/runtime/control-plane/execution/work-remote-delivery.ts +2 -3
  345. package/src/runtime/control-plane/execution/work-revision-diff.ts +39 -0
  346. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +201 -199
  347. package/src/runtime/control-plane/execution/work-validation-reconciler.ts +33 -85
  348. package/src/runtime/control-plane/execution/work-verification-service.ts +406 -50
  349. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +6 -2
  350. package/src/runtime/control-plane/facade/capability-registry.ts +364 -37
  351. package/src/runtime/control-plane/facade/check-normalization.ts +3 -9
  352. package/src/runtime/control-plane/facade/codex-delegation.ts +10 -11
  353. package/src/runtime/control-plane/facade/controller-connection.ts +135 -0
  354. package/src/runtime/control-plane/facade/goal-workloop-access.ts +1 -20
  355. package/src/runtime/control-plane/facade/goal-workloop.ts +281 -1753
  356. package/src/runtime/control-plane/facade/handoff-inbox-application.ts +12 -25
  357. package/src/runtime/control-plane/facade/handoff-inbox-store.ts +256 -52
  358. package/src/runtime/control-plane/facade/index.ts +0 -1
  359. package/src/runtime/control-plane/facade/operation-digest.ts +12 -15
  360. package/src/runtime/control-plane/facade/plan-contract-store.ts +451 -991
  361. package/src/runtime/control-plane/facade/policy-gate.ts +0 -23
  362. package/src/runtime/control-plane/facade/repository-work-admission.ts +12 -22
  363. package/src/runtime/control-plane/facade/requirement-authority.ts +102 -199
  364. package/src/runtime/control-plane/facade/requirement-board.ts +3 -3
  365. package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +51 -14
  366. package/src/runtime/control-plane/facade/self-healing-loop.ts +18 -53
  367. package/src/runtime/control-plane/facade/suggested-actions.ts +15 -18
  368. package/src/runtime/control-plane/facade/types.ts +49 -108
  369. package/src/runtime/control-plane/facade/work-continuation.ts +9 -9
  370. package/src/runtime/control-plane/generated-cache-retention.ts +206 -59
  371. package/src/runtime/control-plane/global-scheduler/autonomous-continuation.ts +248 -0
  372. package/src/runtime/control-plane/global-scheduler/durable-admission.ts +1 -1
  373. package/src/runtime/control-plane/global-scheduler/maintenance.ts +256 -117
  374. package/src/runtime/control-plane/global-scheduler/reconciliation.ts +3 -12
  375. package/src/runtime/control-plane/global-scheduler/scheduler.ts +66 -40
  376. package/src/runtime/control-plane/global-scheduler/wake-signal.ts +42 -2
  377. package/src/runtime/control-plane/governance/access-policy.ts +19 -2
  378. package/src/runtime/control-plane/governance/authorization.ts +20 -3
  379. package/src/runtime/control-plane/governance/external-effects.ts +1 -1
  380. package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +63 -300
  381. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +29 -300
  382. package/src/runtime/control-plane/launcher/local-conversation-controller.ts +238 -0
  383. package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +5 -2
  384. package/src/runtime/control-plane/launcher/thin-launcher.ts +96 -240
  385. package/src/runtime/control-plane/persistence/cognition-store.ts +820 -0
  386. package/src/runtime/control-plane/persistence/experience-store.ts +162 -29
  387. package/src/runtime/control-plane/persistence/requirement-store.ts +216 -74
  388. package/src/runtime/control-plane/persistence/sqlite-store.ts +113 -6
  389. package/src/runtime/control-plane/release-retention.ts +135 -47
  390. package/src/runtime/control-plane/repository-namespace-retention.ts +2 -2
  391. package/src/runtime/control-plane/runtime-cleanup.ts +295 -107
  392. package/src/runtime/control-plane/workspace/project-onboarding.ts +80 -0
  393. package/src/runtime/control-plane/workspace/semantic-sync-service.ts +19 -5
  394. package/src/runtime/control-plane/workspace/workspace-store.ts +169 -0
  395. package/src/runtime/diagnostics/incident-repair.ts +313 -146
  396. package/src/runtime/diagnostics/mcp-timing.ts +114 -0
  397. package/src/runtime/evidence/artifact-store.ts +158 -40
  398. package/src/runtime/evidence/evidence-store.ts +112 -8
  399. package/src/runtime/evidence/output-handle-index.ts +225 -0
  400. package/src/runtime/evidence/result-store.ts +158 -44
  401. package/src/runtime/evidence/sensitive-output.ts +22 -2
  402. package/src/runtime/execution/jobs/child-reference.ts +11 -0
  403. package/src/runtime/execution/jobs/receipt-recovery.ts +1 -11
  404. package/src/runtime/execution/jobs/store.ts +3 -4
  405. package/src/runtime/execution/managed-workspace.ts +57 -0
  406. package/src/runtime/execution/process-runtime/check-facade.ts +1 -1
  407. package/src/runtime/execution/process-runtime/check-result-retention.ts +2 -2
  408. package/src/runtime/execution/process-runtime/check-result.ts +105 -1
  409. package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +18 -8
  410. package/src/runtime/execution/process-runtime/command-facade.ts +82 -30
  411. package/src/runtime/execution/process-runtime/gc.ts +15 -2
  412. package/src/runtime/execution/process-runtime/handle-index.ts +176 -0
  413. package/src/runtime/execution/process-runtime/host-command-lane.ts +139 -0
  414. package/src/runtime/execution/process-runtime/index.ts +3 -0
  415. package/src/runtime/execution/process-runtime/lightweight-managed.ts +251 -72
  416. package/src/runtime/execution/process-runtime/persisted-check.ts +3 -3
  417. package/src/runtime/execution/process-runtime/process-runner-entry.ts +47 -5
  418. package/src/runtime/execution/process-runtime/process-scope.ts +160 -0
  419. package/src/runtime/execution/process-runtime/resource-claims.ts +65 -61
  420. package/src/runtime/execution/process-runtime/runtime.ts +55 -18
  421. package/src/runtime/execution/process-runtime/store.ts +30 -2
  422. package/src/runtime/execution/process-runtime/types.ts +6 -1
  423. package/src/runtime/execution/thin-harness/execution-router.ts +16 -16
  424. package/src/runtime/execution/thin-harness/fast-executor.ts +2 -2
  425. package/src/runtime/execution/thin-harness/search-worker.ts +2 -2
  426. package/src/runtime/execution/workers/executor.ts +3 -8
  427. package/src/runtime/maintenance/cleanup.ts +41 -5
  428. package/src/runtime/platform/service-inventory.ts +130 -0
  429. package/src/runtime/platform/service-manager.ts +8 -0
  430. package/src/runtime/plugins/action-application.ts +97 -29
  431. package/src/runtime/plugins/app-store-connect-adapter.ts +290 -18
  432. package/src/runtime/plugins/browser-adapter.ts +1124 -333
  433. package/src/runtime/plugins/browser-automation-service.ts +23 -3
  434. package/src/runtime/plugins/browser-macos-bridge.ts +431 -137
  435. package/src/runtime/plugins/browser-manifest-surface.ts +47 -12
  436. package/src/runtime/plugins/browser-native-session-service.ts +63 -13
  437. package/src/runtime/plugins/browser-registration.ts +18 -0
  438. package/src/runtime/plugins/browser-runtime.ts +40 -36
  439. package/src/runtime/plugins/browser-session-authority.ts +2 -2
  440. package/src/runtime/plugins/browser-session-store.ts +46 -76
  441. package/src/runtime/plugins/capability-authorization-grants.ts +258 -62
  442. package/src/runtime/plugins/computer-chatgpt-browser-adapter-installer.ts +228 -0
  443. package/src/runtime/plugins/computer-registration.ts +298 -20
  444. package/src/runtime/plugins/desktop-operator-external-policy.ts +36 -4
  445. package/src/runtime/plugins/desktop-operator-registration.ts +12 -4
  446. package/src/runtime/plugins/external-adapter.ts +42 -6
  447. package/src/runtime/plugins/external-registration.ts +21 -1
  448. package/src/runtime/plugins/github-adapter.ts +30 -3
  449. package/src/runtime/plugins/gmail-adapter.ts +189 -3
  450. package/src/runtime/plugins/google-calendar-adapter.ts +2 -2
  451. package/src/runtime/plugins/google-shared.ts +24 -12
  452. package/src/runtime/plugins/google-tasks-adapter.ts +2 -2
  453. package/src/runtime/plugins/ios/remote-xpc-hid.ts +70 -30
  454. package/src/runtime/plugins/ios-adapter.ts +46 -41
  455. package/src/runtime/plugins/ios-agent-device.ts +54 -4
  456. package/src/runtime/plugins/ios-device-ownership.ts +103 -0
  457. package/src/runtime/plugins/ios-physical-device.ts +497 -79
  458. package/src/runtime/plugins/lightweight-action.ts +208 -2
  459. package/src/runtime/plugins/local-system-adapter.ts +12 -100
  460. package/src/runtime/plugins/managed-process-adapter.ts +12 -5
  461. package/src/runtime/plugins/plugin-action-sidecar.ts +17 -13
  462. package/src/runtime/plugins/plugin-management-adapter.ts +1 -1
  463. package/src/runtime/plugins/store.ts +682 -435
  464. package/src/runtime/plugins/types.ts +24 -0
  465. package/src/runtime/plugins/xiaohongshu-publish.ts +16 -0
  466. package/src/runtime/projections/git-status-sampler.ts +2 -19
  467. package/src/runtime/projections/invalidation.ts +7 -3
  468. package/src/runtime/projections/materialized-view.ts +80 -36
  469. package/src/runtime/recovery/actions.ts +4 -4
  470. package/src/runtime/recovery/capability-action-application.ts +46 -45
  471. package/src/runtime/recovery/lifecycle-inventory.ts +30 -40
  472. package/src/runtime/recovery/maintenance-executor.ts +374 -123
  473. package/src/runtime/recovery/probe.ts +2 -2
  474. package/src/runtime/recovery/store.ts +29 -11
  475. package/src/runtime/release/release-coordinator.ts +312 -0
  476. package/src/runtime/release/release-session.ts +716 -0
  477. package/src/runtime/release/release-state-migration.ts +25 -0
  478. package/src/runtime/resources/leases/store.ts +56 -25
  479. package/src/runtime/root/computer-composition.ts +191 -6
  480. package/src/runtime/root/controller-progression-composition.ts +254 -0
  481. package/src/runtime/root/controller-round-composition.ts +20 -1
  482. package/src/runtime/root/deployment-topology.ts +106 -0
  483. package/src/runtime/root/entry.ts +4 -3
  484. package/src/runtime/root/known-good-recovery.ts +184 -0
  485. package/src/runtime/root/local-bridge.ts +0 -1
  486. package/src/runtime/root/mcp-transport.ts +111 -18
  487. package/src/runtime/root/ownership.ts +261 -9
  488. package/src/runtime/root/package-connector-service.ts +227 -29
  489. package/src/runtime/root/package-runtime-release.ts +117 -30
  490. package/src/runtime/root/package-runtime-service.ts +24 -24
  491. package/src/runtime/root/release-execution-canary.ts +57 -12
  492. package/src/runtime/root/release-loader.ts +90 -8
  493. package/src/runtime/root/release-manifest.ts +80 -40
  494. package/src/runtime/root/release-materialize.ts +372 -106
  495. package/src/runtime/root/release-store.ts +395 -36
  496. package/src/runtime/root/runtime-lane.ts +191 -0
  497. package/src/runtime/root/runtime.ts +160 -29
  498. package/src/runtime/root/scheduled-controller-composition.ts +29 -3
  499. package/src/runtime/root/service-runner.ts +2 -2
  500. package/src/runtime/root/service.ts +126 -44
  501. package/src/runtime/root/status.ts +48 -0
  502. package/src/runtime/root/types.ts +32 -9
  503. package/src/runtime/root/workflow-supervisor-composition.ts +681 -0
  504. package/src/runtime/root/workflow-supervisor-runtime.ts +564 -0
  505. package/src/runtime/root/write-fence.ts +50 -2
  506. package/src/runtime/safe-tooling/google-credential-store.ts +67 -22
  507. package/src/runtime/safe-tooling/google-oauth-broker.ts +25 -7
  508. package/src/runtime/safe-tooling/ios-development.ts +22 -8
  509. package/src/runtime/safe-tooling/job-summary.ts +1 -1
  510. package/src/runtime/safe-tooling/workspace-auth.ts +5 -2
  511. package/src/runtime/shared/atomic-text-file.ts +21 -0
  512. package/src/runtime/shared/bounded-child-supervisor.ts +9 -1
  513. package/src/runtime/shared/json-files.ts +8 -3
  514. package/src/runtime/shared/process-environment.ts +20 -9
  515. package/src/runtime/shared/response-budget.ts +1 -3
  516. package/src/runtime/standalone-recovery/controller-home-migration.ts +16 -24
  517. package/src/runtime/standalone-recovery/core.ts +3792 -417
  518. package/src/runtime/standalone-recovery/entry.ts +507 -45
  519. package/src/runtime/standalone-recovery/installer.ts +262 -148
  520. package/src/runtime/standalone-recovery/mcp-server.ts +29 -193
  521. package/src/runtime/standalone-recovery/operation-lock.ts +12 -2
  522. package/src/runtime/standalone-recovery/performance.ts +54 -16
  523. package/src/runtime/standalone-recovery/release.ts +53 -5
  524. package/src/runtime/standalone-recovery/service-labels.ts +5 -2
  525. package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +5 -2
  526. package/src/runtime/workflow/schedules/browser-probe.ts +17 -6
  527. package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +11 -3
  528. package/src/runtime/workflow/schedules/engine.ts +166 -178
  529. package/src/runtime/workflow/schedules/pending-activation.ts +11 -4
  530. package/src/runtime/workflow/schedules/work-continuation.ts +95 -11
  531. package/src/runtime/workflows/runtime.ts +15 -19
  532. package/src/testing/test-governance.ts +5 -1
  533. package/supervisor/chatgpt-conversation.ts +23 -0
  534. package/supervisor/client.ts +218 -0
  535. package/supervisor/control-plane.ts +963 -0
  536. package/supervisor/entry.ts +15 -0
  537. package/supervisor/forge-validators.ts +147 -0
  538. package/supervisor/index.ts +5 -0
  539. package/supervisor/native-browser-adapter.ts +1151 -0
  540. package/supervisor/native-messaging/host.ts +58 -0
  541. package/supervisor/native-messaging/manifest.ts +26 -0
  542. package/supervisor/native-messaging/protocol.ts +27 -0
  543. package/supervisor/paths.ts +18 -0
  544. package/supervisor/protocol.ts +250 -0
  545. package/supervisor/server.ts +412 -0
  546. package/supervisor/store.ts +1870 -0
  547. package/supervisor/tsconfig.json +8 -0
  548. package/supervisor/types.ts +261 -0
  549. package/SKILL.md +0 -427
  550. package/adapters/chatgpt/controller-host.ts +0 -119
  551. package/adapters/mcp/controller-round-compatibility.ts +0 -184
  552. package/adapters/mcp/frozen-client-semantic-compatibility.ts +0 -292
  553. package/adapters/mcp/runtime-gateway/work-compat-adapter.ts +0 -502
  554. package/adapters/mcp/runtime-gateway/work-validation-reconciler.ts +0 -1
  555. package/adapters/mcp/toolset-selection.ts +0 -41
  556. package/agents/openai.yaml +0 -4
  557. package/assets/skill-hooks.json +0 -41
  558. package/assets/skill-version.json +0 -189
  559. package/assets/skills/claude-review/SKILL.md +0 -231
  560. package/assets/skills/codex-review/SKILL.md +0 -103
  561. package/assets/templates/helpers/check-skill-version.ts +0 -193
  562. package/packages/kernel/progression/api/index.ts +0 -2
  563. package/packages/kernel/progression/application/projector.ts +0 -211
  564. package/packages/kernel/progression/domain/types.ts +0 -116
  565. package/packages/kernel/progression/index.ts +0 -1
  566. package/packages/kernel/scheduler/application/continuation-service.ts +0 -212
  567. package/packages/kernel/scheduler/domain/continuation.ts +0 -38
  568. package/packages/kernel/scheduler/infrastructure/continuation-dispatch-store.ts +0 -38
  569. package/packages/kernel/work/domain/admission-policy.ts +0 -34
  570. package/scripts/benchmark-background-check-overlap.ts +0 -228
  571. package/scripts/benchmark-computer-hotpath.ts +0 -255
  572. package/scripts/benchmark-controller-hotpath.ts +0 -212
  573. package/scripts/benchmark-controller-round2.ts +0 -191
  574. package/scripts/benchmark-ios-agent-device.ts +0 -511
  575. package/scripts/benchmark-mcp-host.sh +0 -117
  576. package/scripts/benchmark-mcp-transport.ts +0 -169
  577. package/scripts/benchmark-operational-memory-activation.ts +0 -235
  578. package/scripts/benchmark-operational-shadow.ts +0 -28
  579. package/scripts/benchmark-quality-harness.ts +0 -146
  580. package/scripts/benchmark-route-session-concurrency.ts +0 -915
  581. package/scripts/benchmark-thin-harness-gateway-ab.ts +0 -632
  582. package/scripts/benchmark-thin-harness-mcp-e2e.ts +0 -498
  583. package/scripts/benchmark-thin-harness.ts +0 -251
  584. package/scripts/benchmark-typescript-navigation.ts +0 -186
  585. package/scripts/benchmark-work-efficiency.ts +0 -334
  586. package/scripts/build-controller-ui.ts +0 -28
  587. package/scripts/check-npm-release.sh +0 -32
  588. package/scripts/check-public-release-surface.sh +0 -19
  589. package/scripts/check-release-published.sh +0 -57
  590. package/scripts/check-release-readiness.sh +0 -37
  591. package/scripts/check-release-version.mjs +0 -74
  592. package/scripts/check-skill-version.ts +0 -5
  593. package/scripts/check-tarball-install-smoke.sh +0 -150
  594. package/scripts/ensure-codegraph.sh +0 -16
  595. package/scripts/package-source-archive.sh +0 -147
  596. package/scripts/public-release-files.txt +0 -39
  597. package/scripts/public-release.ts +0 -174
  598. package/scripts/publish-release-tarball.sh +0 -27
  599. package/scripts/route-nl-vs-ts-eval.ts +0 -679
  600. package/scripts/run-skill-hook.ts +0 -244
  601. package/scripts/stage-runtime-release.ts +0 -44
  602. package/scripts/sync-codex-installed-copies.sh +0 -182
  603. package/src/cli/commands/tools.ts +0 -167
  604. package/src/cli/controller/progress.ts +0 -656
  605. package/src/cli/controller/work-mode.ts +0 -181
  606. package/src/cli/local-bridge/console-assets.ts +0 -17
  607. package/src/cli/local-bridge/dashboard.ts +0 -17
  608. package/src/cli/local-bridge/frontend/src/App.tsx +0 -10
  609. package/src/cli/local-bridge/frontend/src/components/Button.tsx +0 -1
  610. package/src/cli/local-bridge/frontend/src/components/DetailPane.tsx +0 -3
  611. package/src/cli/local-bridge/frontend/src/components/SearchField.tsx +0 -1
  612. package/src/cli/local-bridge/frontend/src/components/SectionHeader.tsx +0 -1
  613. package/src/cli/local-bridge/frontend/src/components/Segmented.tsx +0 -1
  614. package/src/cli/local-bridge/frontend/src/components/StatusText.tsx +0 -3
  615. package/src/cli/local-bridge/frontend/src/design/icons.tsx +0 -11
  616. package/src/cli/local-bridge/frontend/src/design/tokens.css +0 -8
  617. package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +0 -153
  618. package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +0 -37
  619. package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +0 -183
  620. package/src/cli/local-bridge/frontend/src/features/repositories/RepositoriesView.tsx +0 -2
  621. package/src/cli/local-bridge/frontend/src/features/system/SystemView.tsx +0 -2
  622. package/src/cli/local-bridge/frontend/src/features/work/WorkView.tsx +0 -4
  623. package/src/cli/local-bridge/frontend/src/lib/api.ts +0 -30
  624. package/src/cli/local-bridge/frontend/src/lib/format.ts +0 -4
  625. package/src/cli/local-bridge/frontend/src/lib/routes.ts +0 -7
  626. package/src/cli/local-bridge/frontend/src/main.tsx +0 -1
  627. package/src/cli/local-bridge/frontend/src/shell/AppShell.tsx +0 -1
  628. package/src/cli/local-bridge/frontend/src/shell/CommandBar.tsx +0 -2
  629. package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +0 -4
  630. package/src/cli/local-bridge/frontend/src/styles.css +0 -28
  631. package/src/cli/local-bridge/frontend/src/types.ts +0 -15
  632. package/src/cli/local-bridge/frontend/src/vite-env.d.ts +0 -1
  633. package/src/cli/local-bridge/frontend/vite.config.ts +0 -27
  634. package/src/cli/local-bridge/ui-dist/app.css +0 -1
  635. package/src/cli/local-bridge/ui-dist/app.js +0 -11228
  636. package/src/cli/mcp/access-mode.ts +0 -2
  637. package/src/cli/mcp/access-tools.ts +0 -2
  638. package/src/cli/mcp/audit.ts +0 -2
  639. package/src/cli/mcp/auth.ts +0 -2
  640. package/src/cli/mcp/instructions.ts +0 -2
  641. package/src/cli/mcp/legacy-context.ts +0 -2
  642. package/src/cli/mcp/legacy-tool-service.ts +0 -2
  643. package/src/cli/mcp/multi-repository.ts +0 -2
  644. package/src/cli/mcp/oauth.ts +0 -2
  645. package/src/cli/mcp/openai-secure-tunnel.ts +0 -2
  646. package/src/cli/mcp/paths.ts +0 -2
  647. package/src/cli/mcp/policy.ts +0 -2
  648. package/src/cli/mcp/post-finalize-work-attribution.ts +0 -2
  649. package/src/cli/mcp/proxy-env.ts +0 -2
  650. package/src/cli/mcp/readiness-projection.ts +0 -2
  651. package/src/cli/mcp/redaction.ts +0 -2
  652. package/src/cli/mcp/repo.ts +0 -2
  653. package/src/cli/mcp/repository-tools.ts +0 -2
  654. package/src/cli/mcp/server.ts +0 -2
  655. package/src/cli/mcp/setup.ts +0 -2
  656. package/src/cli/mcp/tool-capability-cache.ts +0 -2
  657. package/src/cli/mcp/tool-contract.ts +0 -2
  658. package/src/cli/mcp/tools.ts +0 -2
  659. package/src/cli/mcp/toolset-names.ts +0 -2
  660. package/src/cli/mcp/toolset-selection.ts +0 -2
  661. package/src/cli/mcp/toolset.ts +0 -2
  662. package/src/cli/mcp/transports/http.ts +0 -2
  663. package/src/cli/mcp/transports/session-registry.ts +0 -2
  664. package/src/cli/mcp/transports/stdio.ts +0 -2
  665. package/src/cli/mcp/types.ts +0 -2
  666. package/src/cli/mcp/umbrella-tools.ts +0 -2
  667. package/src/cli/tools/codegraph.ts +0 -695
  668. package/src/core/adoption/helper-wrapper-plan.ts +0 -159
  669. package/src/runtime/context/codegraph-cache-boundary.ts +0 -255
  670. package/src/runtime/context/codegraph-read-provider.ts +0 -611
  671. package/src/runtime/context/codegraph-sidecar.cjs +0 -248
  672. package/src/runtime/control-plane/codegraph-cache-retention.ts +0 -164
  673. package/src/runtime/control-plane/execution/content-equivalent-commit-authority.ts +0 -169
  674. package/src/runtime/control-plane/execution/direct-canonical-work-reconciliation.ts +0 -85
  675. package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +0 -655
  676. package/src/runtime/control-plane/execution/work-finalization-service.ts +0 -2850
  677. package/src/runtime/control-plane/execution/work-path-scope.ts +0 -37
  678. package/src/runtime/control-plane/execution/work-task-receipt.ts +0 -468
  679. package/src/runtime/control-plane/facade/controller-round-relay.ts +0 -3
  680. package/src/runtime/control-plane/facade/work-admission-policy.ts +0 -142
  681. package/src/runtime/control-plane/facade/work-implementation-review.ts +0 -2
  682. package/src/runtime/control-plane/facade/work-state-machine.ts +0 -2
  683. package/src/runtime/control-plane/facade/work-task-projection.ts +0 -66
  684. package/src/runtime/control-plane/routing/index.ts +0 -1
  685. package/src/runtime/control-plane/routing/route-policy.ts +0 -401
  686. package/src/runtime/control-plane/routing/workspace-admission.ts +0 -70
  687. package/src/runtime/gateway/mcp/execution-tools.ts +0 -2
  688. package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +0 -2
  689. package/src/runtime/gateway/mcp/persisted-check-process.ts +0 -2
  690. package/src/runtime/gateway/mcp/process-tools.ts +0 -2
  691. package/src/runtime/gateway/mcp/router.ts +0 -2
  692. package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +0 -2
  693. package/src/runtime/gateway/mcp/runtime-tools.ts +0 -2
  694. package/src/runtime/gateway/mcp/work-validation-reconciler.ts +0 -2
  695. package/src/runtime/plugins/browser-provider-registry.ts +0 -2
@@ -1,5 +1,5 @@
1
- import { cpSync, lstatSync, mkdirSync, readdirSync, readFileSync, readlinkSync, rmSync } from 'fs';
2
- import { basename, join, resolve } from 'path';
1
+ import { cpSync, lstatSync, mkdirSync, readlinkSync, rmSync } from 'fs';
2
+ import { join, resolve } from 'path';
3
3
  import type {
4
4
  ComputerSurfaceProviderBinding,
5
5
  ComputerSurfaceTarget,
@@ -12,13 +12,24 @@ import {
12
12
  cleanupLegacyBrowserSessionJson,
13
13
  readLegacyBrowserSessionMigrationEntries,
14
14
  } from './browser-session-legacy-migration';
15
- import { writeJsonAtomic } from '../shared/json-files';
16
15
  import { AssistantPluginError } from './errors';
17
16
 
18
17
  const BROWSER_STATE_ROOT = '.forge/browser';
19
18
  const BROWSER_SESSION_COMPATIBILITY_NAMESPACE = 'browser.session.v1';
20
19
  const BROWSER_SESSION_COMPUTER_MIGRATION_ID = 'browser-session-authority-v1-to-computer-surface-v1';
21
20
 
21
+ function requireBrowserSessionExecutionContext() {
22
+ const context = currentRuntimeBrowserSessionExecutionContext();
23
+ if (!context) {
24
+ throw new AssistantPluginError(
25
+ 'PLUGIN_BROWSER_SESSION_CONTEXT_REQUIRED',
26
+ 'Browser session identity is owned by the Computer target authority and requires an explicit Controller execution context.',
27
+ { retryable: false },
28
+ );
29
+ }
30
+ return context;
31
+ }
32
+
22
33
  function unique(values: readonly string[]): string[] {
23
34
  return [...new Set(values.map((value) => value.trim()).filter(Boolean))];
24
35
  }
@@ -109,9 +120,9 @@ function surfaceInput(
109
120
  * Browser actions never read or write Browser-owned durable session state.
110
121
  */
111
122
  export function ensureBrowserSessionsMigratedToComputer(repoRoot: string): number {
112
- const context = currentRuntimeBrowserSessionExecutionContext();
113
- if (!context) return 0;
123
+ const context = requireBrowserSessionExecutionContext();
114
124
  const computer = runtimeComputerInteractionTargetAuthority();
125
+ if (!context.repoId) return 0;
115
126
  if (computer.compatibilityMigrationMarker(context.controllerHome, BROWSER_SESSION_COMPUTER_MIGRATION_ID, context.repoId)) {
116
127
  cleanupLegacyBrowserSessionJson(context.controllerHome, context.repoId, repoRoot);
117
128
  return 0;
@@ -146,8 +157,10 @@ export function ensureBrowserSessionsMigratedToComputer(repoRoot: string): numbe
146
157
  }
147
158
 
148
159
  /** Move legacy provider files out of the repository and retire the old path after migration. */
149
- export function ensureBrowserStateInControllerHome(controllerHome: string, repoId: string, repoRoot: string): string {
150
- const targetRoot = join(controllerHome, 'repositories', repoId, 'browser');
160
+ export function ensureBrowserStateInControllerHome(controllerHome: string, repoId: string | undefined, repoRoot: string): string {
161
+ const targetRoot = repoId
162
+ ? join(controllerHome, 'repositories', repoId, 'browser')
163
+ : join(controllerHome, 'browser');
151
164
  const compatibilityParent = join(repoRoot, '.forge');
152
165
  const compatibilityRoot = join(compatibilityParent, 'browser');
153
166
  mkdirSync(targetRoot, { recursive: true });
@@ -178,50 +191,25 @@ export function ensureBrowserStateInControllerHome(controllerHome: string, repoI
178
191
  /**
179
192
  * Browser semantic identity belongs to Computer SurfaceTarget authority. Provider
180
193
  * working state (profiles, screenshots, downloads, diagnostics) remains
181
- * repository-scoped under Controller Home. Repo-local session JSON exists only
182
- * for standalone compatibility when no Controller execution context is present.
194
+ * repository-scoped under Controller Home. Session identity has no standalone
195
+ * repository-local fallback; callers must supply Controller execution context.
183
196
  */
184
197
  export function browserStateDir(
185
198
  repoRoot: string,
186
199
  name: 'sessions' | 'screenshots' | 'profiles' | 'downloads' | 'diagnostics',
187
200
  ): string {
188
201
  const context = currentRuntimeBrowserSessionExecutionContext();
202
+ if (name === 'sessions') {
203
+ const sessionContext = context ?? requireBrowserSessionExecutionContext();
204
+ return join(ensureBrowserStateInControllerHome(sessionContext.controllerHome, sessionContext.repoId, repoRoot), name);
205
+ }
189
206
  return context
190
207
  ? join(ensureBrowserStateInControllerHome(context.controllerHome, context.repoId, repoRoot), name)
191
208
  : join(repoRoot, BROWSER_STATE_ROOT, name);
192
209
  }
193
210
 
194
- function sessionPath(repoRoot: string, sessionId: string): string {
195
- return join(browserStateDir(repoRoot, 'sessions'), `${sessionId.replace(/[^a-zA-Z0-9_-]/g, '_')}.json`);
196
- }
197
-
198
- function readLegacyBrowserSessionJson(path: string): BrowserSessionState | undefined {
199
- let raw: string;
200
- try {
201
- raw = readFileSync(path, 'utf-8');
202
- } catch (error) {
203
- if ((error as NodeJS.ErrnoException)?.code === 'ENOENT') return undefined;
204
- throw new AssistantPluginError('PLUGIN_BROWSER_SESSION_STATE_READ_FAILED', 'Saved browser session metadata could not be read.', {
205
- retryable: true,
206
- details: { fileName: basename(path), cause: error instanceof Error ? error.message : String(error) },
207
- });
208
- }
209
- try {
210
- return JSON.parse(raw) as BrowserSessionState;
211
- } catch (error) {
212
- throw new AssistantPluginError('PLUGIN_BROWSER_SESSION_STATE_CORRUPT', 'Saved browser session metadata is malformed; refusing to treat corrupt state as a missing session.', {
213
- retryable: false,
214
- details: { fileName: basename(path), cause: error instanceof Error ? error.message : String(error) },
215
- });
216
- }
217
- }
218
-
219
211
  export function saveBrowserSession(repoRoot: string, session: BrowserSessionState): BrowserSessionState {
220
- const context = currentRuntimeBrowserSessionExecutionContext();
221
- if (!context) {
222
- writeJsonAtomic(sessionPath(repoRoot, session.sessionId), session);
223
- return session;
224
- }
212
+ const context = requireBrowserSessionExecutionContext();
225
213
  ensureBrowserSessionsMigratedToComputer(repoRoot);
226
214
  const computer = runtimeComputerInteractionTargetAuthority();
227
215
  const binding = surfaceProviderBinding(session);
@@ -235,7 +223,8 @@ export function saveBrowserSession(repoRoot: string, session: BrowserSessionStat
235
223
  if (!existing) {
236
224
  existing = computer.upsertSurface(context.controllerHome, surfaceInput(session, {
237
225
  aliases: [session.sessionId],
238
- repositoryIds: [context.repoId],
226
+ repositoryIds: context.repoId ? [context.repoId] : [],
227
+ visibility: context.repoId ? undefined : 'controller',
239
228
  includeCompatibility: false,
240
229
  reactivate: true,
241
230
  })).target;
@@ -248,7 +237,8 @@ export function saveBrowserSession(repoRoot: string, session: BrowserSessionStat
248
237
  if (normalized.browser?.sessionResume) normalized.browser.sessionResume.sessionId = canonicalSessionId;
249
238
  const saved = computer.upsertSurface(context.controllerHome, surfaceInput(normalized, {
250
239
  aliases: [session.sessionId, canonicalSessionId],
251
- repositoryIds: [context.repoId],
240
+ repositoryIds: context.repoId ? [context.repoId] : [],
241
+ visibility: context.repoId ? undefined : 'controller',
252
242
  reactivate: true,
253
243
  }));
254
244
  return browserSessionFromSurface(saved.target) ?? normalized;
@@ -256,49 +246,29 @@ export function saveBrowserSession(repoRoot: string, session: BrowserSessionStat
256
246
 
257
247
  export function findBrowserSession(repoRoot: string, sessionId?: string): BrowserSessionState | undefined {
258
248
  if (!sessionId) return undefined;
259
- const context = currentRuntimeBrowserSessionExecutionContext();
260
- if (!context) return readLegacyBrowserSessionJson(sessionPath(repoRoot, sessionId));
249
+ const context = requireBrowserSessionExecutionContext();
261
250
  ensureBrowserSessionsMigratedToComputer(repoRoot);
262
251
  const target = runtimeComputerInteractionTargetAuthority().findSurfaceByAlias(context.controllerHome, sessionId, context.repoId);
263
- return target ? browserSessionFromSurface(target) : undefined;
252
+ if (!target || (!context.repoId && target.visibility !== 'controller')) return undefined;
253
+ return browserSessionFromSurface(target);
264
254
  }
265
255
 
266
256
  export function listSavedBrowserSessions(repoRoot: string): BrowserSessionState[] {
267
- const context = currentRuntimeBrowserSessionExecutionContext();
268
- if (context) {
269
- ensureBrowserSessionsMigratedToComputer(repoRoot);
270
- return runtimeComputerInteractionTargetAuthority().listAllSurfaces(context.controllerHome, { repoId: context.repoId })
271
- .map(browserSessionFromSurface)
272
- .filter((session): session is BrowserSessionState => Boolean(session))
273
- .sort((left, right) => right.updatedAt.localeCompare(left.updatedAt) || left.sessionId.localeCompare(right.sessionId));
274
- }
275
- const root = browserStateDir(repoRoot, 'sessions');
276
- let names: string[];
277
- try {
278
- names = readdirSync(root);
279
- } catch (error) {
280
- if ((error as NodeJS.ErrnoException)?.code === 'ENOENT') return [];
281
- throw new AssistantPluginError('PLUGIN_BROWSER_SESSION_STATE_READ_FAILED', 'Saved browser session directory could not be read.', {
282
- retryable: true,
283
- details: { cause: error instanceof Error ? error.message : String(error) },
284
- });
285
- }
286
- return names
287
- .filter((name) => name.endsWith('.json'))
288
- .map((name) => readLegacyBrowserSessionJson(join(root, name)))
289
- .filter((session): session is BrowserSessionState => Boolean(session));
257
+ const context = requireBrowserSessionExecutionContext();
258
+ ensureBrowserSessionsMigratedToComputer(repoRoot);
259
+ return runtimeComputerInteractionTargetAuthority().listAllSurfaces(context.controllerHome, { repoId: context.repoId })
260
+ .filter((target) => Boolean(context.repoId) || target.visibility === 'controller')
261
+ .map(browserSessionFromSurface)
262
+ .filter((session): session is BrowserSessionState => Boolean(session))
263
+ .sort((left, right) => right.updatedAt.localeCompare(left.updatedAt) || left.sessionId.localeCompare(right.sessionId));
290
264
  }
291
265
 
292
266
  export function removeBrowserSession(repoRoot: string, sessionId: string): void {
293
- const context = currentRuntimeBrowserSessionExecutionContext();
294
- if (context) {
295
- ensureBrowserSessionsMigratedToComputer(repoRoot);
296
- const computer = runtimeComputerInteractionTargetAuthority();
297
- const target = computer.findSurfaceByAlias(context.controllerHome, sessionId, context.repoId);
298
- if (target) computer.tombstoneSurface(context.controllerHome, target.targetId);
299
- return;
300
- }
301
- rmSync(sessionPath(repoRoot, sessionId), { force: true });
267
+ const context = requireBrowserSessionExecutionContext();
268
+ ensureBrowserSessionsMigratedToComputer(repoRoot);
269
+ const computer = runtimeComputerInteractionTargetAuthority();
270
+ const target = computer.findSurfaceByAlias(context.controllerHome, sessionId, context.repoId);
271
+ if (target && (context.repoId || target.visibility === 'controller')) computer.tombstoneSurface(context.controllerHome, target.targetId);
302
272
  }
303
273
 
304
274
  export function loadBrowserSession(repoRoot: string, sessionId?: string): BrowserSessionState | undefined {
@@ -1,5 +1,13 @@
1
+ import {
2
+ findActiveCanonicalGrant,
3
+ listCanonicalGrants,
4
+ reconcileCanonicalGrants,
5
+ recordCanonicalGrant,
6
+ revokeCanonicalGrant,
7
+ type Grant,
8
+ } from '../../../packages/kernel/identity/api/index';
1
9
  import { randomUUID } from 'crypto';
2
- import { existsSync, mkdirSync } from 'fs';
10
+ import { existsSync, renameSync } from 'fs';
3
11
  import { join } from 'path';
4
12
  import { controllerSystemRoot } from '../../cli/repositories/controller-home';
5
13
  import { ControllerLockContentionError, withControllerLock } from '../../cli/repositories/locks';
@@ -31,7 +39,7 @@ export interface PluginCapabilityAuthorizationGrant {
31
39
  schemaVersion: 1;
32
40
  grantId: string;
33
41
  ownerScope: string;
34
- repoId: string;
42
+ repoId?: string;
35
43
  pluginId: string;
36
44
  capabilityId: string;
37
45
  target: AssistantPluginAuthorizationTarget;
@@ -51,7 +59,7 @@ interface PluginCapabilityAuthorizationGrantStore {
51
59
 
52
60
  export interface PluginCapabilityAuthorizationQuery {
53
61
  ownerScope: string;
54
- repoId: string;
62
+ repoId?: string;
55
63
  pluginId: string;
56
64
  capabilityId: string;
57
65
  target: AssistantPluginAuthorizationTarget;
@@ -73,12 +81,19 @@ export interface RevokePluginCapabilityAuthorizationInput {
73
81
  now?: Date;
74
82
  }
75
83
 
76
- const RISK_RANK: Record<AssistantPluginActionRisk, number> = {
77
- readonly: 0,
78
- workspace_write: 1,
79
- remote_write: 2,
80
- destructive: 3,
81
- };
84
+ export interface ReconcilePluginCapabilityAuthorizationsInput {
85
+ retiredOwnerScopes?: readonly string[];
86
+ now?: Date;
87
+ }
88
+
89
+ export interface ReconcilePluginCapabilityAuthorizationsResult {
90
+ removedRetiredOwner: number;
91
+ removedRevoked: number;
92
+ removedExpired: number;
93
+ removedTotal: number;
94
+ remaining: number;
95
+ changed: boolean;
96
+ }
82
97
 
83
98
  const GENERIC_PLUGIN_AUTHORIZATION_ACTORS = new Set(['', 'anonymous', 'plugin_action_execute']);
84
99
 
@@ -156,7 +171,10 @@ function validatePersistedGrant(value: unknown, index: number): PluginCapability
156
171
  schemaVersion: 1,
157
172
  grantId: string('grantId'),
158
173
  ownerScope: string('ownerScope'),
159
- repoId: string('repoId'),
174
+ // Pre-canonical plugin grants could omit repoId for controller/account targets.
175
+ // Normalize that omission once during the one-way migration; authorization
176
+ // against the canonical Grant store is exact after this point.
177
+ repoId: typeof record.repoId === 'string' && record.repoId.trim() ? record.repoId.trim() : 'controller:global',
160
178
  pluginId: string('pluginId'),
161
179
  capabilityId: string('capabilityId'),
162
180
  target: normalizeTarget({
@@ -180,6 +198,41 @@ export function pluginCapabilityAuthorizationGrantStorePath(controllerHome: stri
180
198
  return join(controllerSystemRoot(controllerHome), 'plugin-capability-authorizations', 'grants.json');
181
199
  }
182
200
 
201
+ function legacyPluginGrantMigrationMarkerPath(controllerHome: string): string {
202
+ return join(controllerSystemRoot(controllerHome), 'plugin-capability-authorizations', 'migration.json');
203
+ }
204
+
205
+ /**
206
+ * Durable proof that this Controller Home already ran the one-way migration, so
207
+ * authorization reads stop consulting the legacy file at all.
208
+ */
209
+ interface LegacyPluginGrantMigrationMarker {
210
+ schemaVersion: 1;
211
+ migratedAt: string;
212
+ legacyGrantCount: number;
213
+ canonicalGrantCount: number;
214
+ }
215
+
216
+ function readLegacyPluginGrantMigrationMarker(controllerHome: string): LegacyPluginGrantMigrationMarker | undefined {
217
+ const path = legacyPluginGrantMigrationMarkerPath(controllerHome);
218
+ if (!existsSync(path)) return undefined;
219
+ try {
220
+ const raw = readJsonFile<Record<string, unknown>>(path);
221
+ if (raw?.schemaVersion !== 1
222
+ || typeof raw.migratedAt !== 'string'
223
+ || typeof raw.legacyGrantCount !== 'number'
224
+ || typeof raw.canonicalGrantCount !== 'number') {
225
+ throw new Error('migration marker schema is invalid');
226
+ }
227
+ return raw as unknown as LegacyPluginGrantMigrationMarker;
228
+ } catch (error) {
229
+ throw new PluginCapabilityAuthorizationGrantError(
230
+ 'PLUGIN_CAPABILITY_GRANT_STORE_CORRUPT',
231
+ `Plugin capability authorization migration marker is corrupt: ${error instanceof Error ? error.message : String(error)}`,
232
+ );
233
+ }
234
+ }
235
+
183
236
  function loadStore(controllerHome: string): PluginCapabilityAuthorizationGrantStore {
184
237
  const path = pluginCapabilityAuthorizationGrantStorePath(controllerHome);
185
238
  if (!existsSync(path)) return { schemaVersion: 1, grants: [] };
@@ -197,21 +250,123 @@ function loadStore(controllerHome: string): PluginCapabilityAuthorizationGrantSt
197
250
  }
198
251
  }
199
252
 
200
- function saveStore(controllerHome: string, store: PluginCapabilityAuthorizationGrantStore): void {
201
- const path = pluginCapabilityAuthorizationGrantStorePath(controllerHome);
202
- mkdirSync(join(controllerSystemRoot(controllerHome), 'plugin-capability-authorizations'), { recursive: true });
203
- writeJsonAtomic(path, store);
253
+ function pluginMetadataFromCanonicalGrant(grant: Grant): { pluginId: string; capabilityId: string } | undefined {
254
+ const constraints = grant.constraints;
255
+ if (!constraints || constraints.kind !== 'plugin_capability_authorization') return undefined;
256
+ const pluginId = typeof constraints.pluginId === 'string' ? constraints.pluginId.trim() : '';
257
+ const capabilityId = typeof constraints.capabilityId === 'string' ? constraints.capabilityId.trim() : '';
258
+ return pluginId && capabilityId ? { pluginId, capabilityId } : undefined;
259
+ }
260
+
261
+ function pluginGrantFromCanonical(
262
+ grant: Grant,
263
+ fallback?: { pluginId: string; capabilityId: string; repoId?: string; target?: AssistantPluginAuthorizationTarget },
264
+ ): PluginCapabilityAuthorizationGrant | undefined {
265
+ const metadata = pluginMetadataFromCanonicalGrant(grant)
266
+ ?? (fallback ? { pluginId: fallback.pluginId, capabilityId: fallback.capabilityId } : undefined);
267
+ if (!metadata || !grant.target) return undefined;
268
+ if (grant.riskCeiling === 'destructive') return undefined;
269
+ const ownerScope = grant.ownerScope?.trim() || grant.principalId.trim();
270
+ if (!ownerScope) return undefined;
271
+ const target: AssistantPluginAuthorizationTarget = {
272
+ kind: grant.target.kind,
273
+ id: grant.target.id,
274
+ ...(grant.target.identityFingerprint ? { identityFingerprint: grant.target.identityFingerprint } : fallback?.target?.identityFingerprint ? { identityFingerprint: fallback.target.identityFingerprint } : {}),
275
+ };
276
+ return {
277
+ schemaVersion: 1,
278
+ grantId: grant.grantId,
279
+ ownerScope,
280
+ repoId: grant.target.repoId ?? fallback?.repoId ?? 'controller:global',
281
+ pluginId: metadata.pluginId,
282
+ capabilityId: metadata.capabilityId,
283
+ target,
284
+ scopes: [...(grant.scopes ?? [])],
285
+ riskCeiling: grant.riskCeiling ?? 'readonly',
286
+ createdAt: grant.createdAt,
287
+ updatedAt: grant.updatedAt,
288
+ expiresAt: grant.expiresAt,
289
+ ...(grant.revokedAt ? { revokedAt: grant.revokedAt } : {}),
290
+ ...(grant.revokedReason ? { revokedReason: grant.revokedReason } : {}),
291
+ };
204
292
  }
205
293
 
206
- function targetMatches(left: AssistantPluginAuthorizationTarget, right: AssistantPluginAuthorizationTarget): boolean {
207
- return left.kind === right.kind
208
- && left.id === right.id
209
- && (left.identityFingerprint ?? '') === (right.identityFingerprint ?? '');
294
+ function recordCanonicalPluginGrant(
295
+ controllerHome: string,
296
+ grant: PluginCapabilityAuthorizationGrant,
297
+ now?: Date,
298
+ ): PluginCapabilityAuthorizationGrant {
299
+ const expiresInMinutes = Math.max(1, Math.ceil((Date.parse(grant.expiresAt) - (now ?? new Date()).getTime()) / 60_000));
300
+ const canonical = recordCanonicalGrant(controllerHome, {
301
+ grantId: grant.grantId,
302
+ principalId: grant.ownerScope,
303
+ ownerScope: grant.ownerScope,
304
+ capabilities: [`${grant.pluginId}:${grant.capabilityId}`, grant.capabilityId],
305
+ target: {
306
+ kind: grant.target.kind,
307
+ id: grant.target.id,
308
+ repoId: grant.repoId,
309
+ ...(grant.target.identityFingerprint ? { identityFingerprint: grant.target.identityFingerprint } : {}),
310
+ },
311
+ scopes: grant.scopes,
312
+ riskCeiling: grant.riskCeiling,
313
+ constraints: { kind: 'plugin_capability_authorization', pluginId: grant.pluginId, capabilityId: grant.capabilityId },
314
+ expiresInMinutes,
315
+ now,
316
+ });
317
+ return pluginGrantFromCanonical(canonical, grant)!;
210
318
  }
211
319
 
212
- function scopesContain(granted: readonly string[], requested: readonly string[]): boolean {
213
- const available = new Set(granted);
214
- return requested.every((scope) => available.has(scope));
320
+ /**
321
+ * One-way migration input. The legacy plugin grant file is read-only history:
322
+ * every still-authorizable legacy grant is copied into the canonical Grant
323
+ * authority exactly once, and this module never writes the legacy file again.
324
+ * A corrupt migration input still fails closed so un-migrated grants cannot be
325
+ * silently dropped.
326
+ *
327
+ * Removal trigger: once a released Runtime baseline has shipped with the
328
+ * `migration.json` marker (so every install has migrated at least once), delete
329
+ * this migration, `loadStore`/`validatePersistedGrant`, the legacy path getter
330
+ * and the PLUGIN_CAPABILITY_GRANT_STORE_CORRUPT error code in the same slice.
331
+ * The archived `grants.json.migrated-*` file is recoverable history, not input.
332
+ */
333
+ function migrateLegacyPluginCapabilityGrants(controllerHome: string, at = new Date()): void {
334
+ if (readLegacyPluginGrantMigrationMarker(controllerHome)) return;
335
+ const legacyGrants = loadStore(controllerHome).grants;
336
+ const canonicalById = new Map(listCanonicalGrants(controllerHome).map((grant) => [grant.grantId, grant]));
337
+ const atMs = at.getTime();
338
+ for (const grant of legacyGrants) {
339
+ if (grant.revokedAt) continue;
340
+ if (Date.parse(grant.expiresAt) <= atMs) continue;
341
+ const existing = canonicalById.get(grant.grantId);
342
+ if (existing) {
343
+ // A canonical row written before plugin metadata existed cannot be projected
344
+ // back into a plugin grant. Repair it in place instead of leaving a live grant
345
+ // that neither list nor by-id resolution can see.
346
+ if (existing.revokedAt || pluginMetadataFromCanonicalGrant(existing)) continue;
347
+ recordCanonicalPluginGrant(controllerHome, grant, new Date(grant.createdAt));
348
+ continue;
349
+ }
350
+ recordCanonicalPluginGrant(controllerHome, grant, new Date(grant.createdAt));
351
+ canonicalById.set(grant.grantId, { grantId: grant.grantId } as Grant);
352
+ }
353
+ // The migration is complete for this Controller Home: prove it durably, then
354
+ // move the legacy file aside so no authorization read can ever depend on it
355
+ // again. The archive is recoverable; a failed rename leaves an inert file.
356
+ writeJsonAtomic(legacyPluginGrantMigrationMarkerPath(controllerHome), {
357
+ schemaVersion: 1,
358
+ migratedAt: at.toISOString(),
359
+ legacyGrantCount: legacyGrants.length,
360
+ canonicalGrantCount: listCanonicalGrants(controllerHome).length,
361
+ } satisfies LegacyPluginGrantMigrationMarker);
362
+ const legacyPath = pluginCapabilityAuthorizationGrantStorePath(controllerHome);
363
+ if (existsSync(legacyPath)) {
364
+ try {
365
+ renameSync(legacyPath, `${legacyPath}.migrated-${at.getTime()}`);
366
+ } catch {
367
+ // Inert history; the marker already prevents any further legacy read.
368
+ }
369
+ }
215
370
  }
216
371
 
217
372
  export function findActivePluginCapabilityAuthorization(
@@ -220,22 +375,21 @@ export function findActivePluginCapabilityAuthorization(
220
375
  ): PluginCapabilityAuthorizationGrant | undefined {
221
376
  if (query.risk === 'destructive') return undefined;
222
377
  const ownerScope = required(query.ownerScope, 'ownerScope');
223
- const repoId = required(query.repoId, 'repoId');
378
+ const repoId = (query.repoId?.trim()) || 'controller:global';
224
379
  const pluginId = required(query.pluginId, 'pluginId');
225
380
  const capabilityId = required(query.capabilityId, 'capabilityId');
226
381
  const target = normalizeTarget(query.target);
227
382
  const scopes = normalizeScopes(query.scopes);
228
- const atMs = (query.at ?? new Date()).getTime();
229
- return loadStore(controllerHome).grants
230
- .filter((grant) => !grant.revokedAt && Date.parse(grant.expiresAt) > atMs)
231
- .filter((grant) => grant.ownerScope === ownerScope
232
- && grant.repoId === repoId
233
- && grant.pluginId === pluginId
234
- && grant.capabilityId === capabilityId
235
- && targetMatches(grant.target, target)
236
- && scopesContain(grant.scopes, scopes)
237
- && RISK_RANK[grant.riskCeiling] >= RISK_RANK[query.risk])
238
- .sort((left, right) => Date.parse(right.updatedAt) - Date.parse(left.updatedAt))[0];
383
+ migrateLegacyPluginCapabilityGrants(controllerHome, query.at ?? new Date());
384
+ const canonical = findActiveCanonicalGrant(controllerHome, {
385
+ ownerScope,
386
+ capability: `${pluginId}:${capabilityId}`,
387
+ target: { kind: target.kind, id: target.id, repoId, ...(target.identityFingerprint ? { identityFingerprint: target.identityFingerprint } : {}) },
388
+ scopes,
389
+ risk: query.risk,
390
+ at: query.at,
391
+ });
392
+ return canonical ? pluginGrantFromCanonical(canonical, { pluginId, capabilityId, repoId, target }) : undefined;
239
393
  }
240
394
 
241
395
  /**
@@ -250,9 +404,12 @@ export function findActivePluginCapabilityAuthorizationById(
250
404
  ): PluginCapabilityAuthorizationGrant | undefined {
251
405
  const normalizedGrantId = required(grantId, 'grantId');
252
406
  const atMs = at.getTime();
253
- const grant = loadStore(controllerHome).grants.find((entry) => entry.grantId === normalizedGrantId);
254
- if (!grant || grant.revokedAt || Date.parse(grant.expiresAt) <= atMs) return undefined;
255
- return structuredClone(grant);
407
+ migrateLegacyPluginCapabilityGrants(controllerHome, at);
408
+ const canonical = listCanonicalGrants(controllerHome).find((entry) => entry.grantId === normalizedGrantId);
409
+ if (canonical && !canonical.revokedAt && Date.parse(canonical.expiresAt) > atMs) {
410
+ return pluginGrantFromCanonical(canonical);
411
+ }
412
+ return undefined;
256
413
  }
257
414
 
258
415
  export function recordPluginCapabilityAuthorization(
@@ -267,7 +424,7 @@ export function recordPluginCapabilityAuthorization(
267
424
  }
268
425
  const now = input.now ?? new Date();
269
426
  const ownerScope = required(input.ownerScope, 'ownerScope');
270
- const repoId = required(input.repoId, 'repoId');
427
+ const repoId = (input.repoId?.trim()) || 'controller:global';
271
428
  const pluginId = required(input.pluginId, 'pluginId');
272
429
  const capabilityId = required(input.capabilityId, 'capabilityId');
273
430
  const target = normalizeTarget(input.target);
@@ -278,6 +435,7 @@ export function recordPluginCapabilityAuthorization(
278
435
  }
279
436
  const expiresInMinutes = Math.min(Math.max(1, Math.trunc(rawMinutes)), MAX_PLUGIN_CAPABILITY_GRANT_MINUTES);
280
437
  const timestamp = now.toISOString();
438
+ migrateLegacyPluginCapabilityGrants(controllerHome, now);
281
439
  const grant: PluginCapabilityAuthorizationGrant = {
282
440
  schemaVersion: 1,
283
441
  grantId: `plugin-grant-${randomUUID()}`,
@@ -298,16 +456,19 @@ export function recordPluginCapabilityAuthorization(
298
456
  { scope: 'global', resource: 'plugin-capability-authorization-grants' },
299
457
  `plugin-capability-grant:${ownerScope}`,
300
458
  () => {
301
- const store = loadStore(controllerHome);
302
- store.grants = store.grants.filter((entry) => !(entry.ownerScope === ownerScope
303
- && entry.repoId === repoId
304
- && entry.pluginId === pluginId
305
- && entry.capabilityId === capabilityId
306
- && entry.target.kind === target.kind
307
- && entry.target.id === target.id));
308
- store.grants.push(grant);
309
- saveStore(controllerHome, store);
310
- return grant;
459
+ const canonicalGrant = recordCanonicalGrant(controllerHome, {
460
+ grantId: grant.grantId,
461
+ principalId: grant.ownerScope,
462
+ ownerScope: grant.ownerScope,
463
+ capabilities: [`${grant.pluginId}:${grant.capabilityId}`, grant.capabilityId],
464
+ target: { kind: grant.target.kind, id: grant.target.id, repoId: grant.repoId, ...(grant.target.identityFingerprint ? { identityFingerprint: grant.target.identityFingerprint } : {}) },
465
+ scopes: grant.scopes,
466
+ riskCeiling: grant.riskCeiling,
467
+ constraints: { kind: 'plugin_capability_authorization', pluginId: grant.pluginId, capabilityId: grant.capabilityId },
468
+ expiresInMinutes,
469
+ now,
470
+ });
471
+ return pluginGrantFromCanonical(canonicalGrant, grant)!;
311
472
  },
312
473
  5_000,
313
474
  );
@@ -333,22 +494,56 @@ export function revokePluginCapabilityAuthorization(
333
494
  { scope: 'global', resource: 'plugin-capability-authorization-grants' },
334
495
  `plugin-capability-revoke:${ownerScope}`,
335
496
  () => {
336
- const store = loadStore(controllerHome);
337
- const index = store.grants.findIndex((grant) => grant.grantId === grantId);
338
- if (index < 0) throw new PluginCapabilityAuthorizationGrantError('PLUGIN_CAPABILITY_GRANT_NOT_FOUND', `Grant ${grantId} was not found.`);
339
- const current = store.grants[index]!;
497
+ const current = findActivePluginCapabilityAuthorizationById(controllerHome, grantId, now);
498
+ if (!current) throw new PluginCapabilityAuthorizationGrantError('PLUGIN_CAPABILITY_GRANT_NOT_FOUND', `Grant ${grantId} was not found.`);
340
499
  if (current.ownerScope !== ownerScope) {
341
500
  throw new PluginCapabilityAuthorizationGrantError('PLUGIN_CAPABILITY_GRANT_OWNER_MISMATCH', `Grant ${grantId} belongs to another owner scope.`);
342
501
  }
343
- const revoked: PluginCapabilityAuthorizationGrant = {
344
- ...current,
345
- updatedAt: now.toISOString(),
346
- revokedAt: now.toISOString(),
347
- revokedReason: reason,
502
+ const canonical = revokeCanonicalGrant(controllerHome, { grantId, ownerScope, reason, now });
503
+ return pluginGrantFromCanonical(canonical, current)!;
504
+ },
505
+ 5_000,
506
+ );
507
+ } catch (error) {
508
+ if (error instanceof ControllerLockContentionError) {
509
+ throw new PluginCapabilityAuthorizationGrantError('PLUGIN_CAPABILITY_GRANT_STORE_BUSY', error.message);
510
+ }
511
+ throw error;
512
+ }
513
+ }
514
+
515
+ export function reconcilePluginCapabilityAuthorizations(
516
+ controllerHome: string,
517
+ input: ReconcilePluginCapabilityAuthorizationsInput = {},
518
+ ): ReconcilePluginCapabilityAuthorizationsResult {
519
+ const retiredOwnerScopes = new Set(
520
+ (input.retiredOwnerScopes ?? [])
521
+ .map((ownerScope) => required(ownerScope, 'retiredOwnerScopes[]')),
522
+ );
523
+ const nowMs = (input.now ?? new Date()).getTime();
524
+ try {
525
+ return withControllerLock(
526
+ controllerHome,
527
+ { scope: 'global', resource: 'plugin-capability-authorization-grants' },
528
+ 'plugin-capability-reconcile',
529
+ () => {
530
+ void nowMs;
531
+ migrateLegacyPluginCapabilityGrants(controllerHome, input.now ?? new Date());
532
+ const canonical = reconcileCanonicalGrants(controllerHome, {
533
+ retiredOwnerScopes: [...retiredOwnerScopes],
534
+ now: input.now,
535
+ });
536
+ const grants = listCanonicalGrants(controllerHome)
537
+ .map((grant) => pluginGrantFromCanonical(grant))
538
+ .filter((grant): grant is PluginCapabilityAuthorizationGrant => Boolean(grant));
539
+ return {
540
+ removedRetiredOwner: canonical.removedRetiredOwner,
541
+ removedRevoked: canonical.removedRevoked,
542
+ removedExpired: canonical.removedExpired,
543
+ removedTotal: canonical.removedTotal,
544
+ remaining: grants.length,
545
+ changed: canonical.changed,
348
546
  };
349
- store.grants[index] = revoked;
350
- saveStore(controllerHome, store);
351
- return revoked;
352
547
  },
353
548
  5_000,
354
549
  );
@@ -364,8 +559,9 @@ export function listPluginCapabilityAuthorizations(
364
559
  controllerHome: string,
365
560
  ownerScope?: string,
366
561
  ): PluginCapabilityAuthorizationGrant[] {
562
+ migrateLegacyPluginCapabilityGrants(controllerHome);
367
563
  const normalizedOwner = ownerScope?.trim();
368
- return loadStore(controllerHome).grants
369
- .filter((grant) => !normalizedOwner || grant.ownerScope === normalizedOwner)
370
- .map((grant) => structuredClone(grant));
564
+ return listCanonicalGrants(controllerHome, normalizedOwner ? { ownerScope: normalizedOwner } : undefined)
565
+ .map((grant) => pluginGrantFromCanonical(grant))
566
+ .filter((grant): grant is PluginCapabilityAuthorizationGrant => Boolean(grant));
371
567
  }