@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
@@ -0,0 +1,284 @@
1
+ import { randomUUID } from 'crypto';
2
+ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'fs';
3
+ import { dirname, join, resolve } from 'path';
4
+ import type {
5
+ Grant,
6
+ GrantTarget,
7
+ QueryGrantInput,
8
+ ReconcileGrantsInput,
9
+ ReconcileGrantsResult,
10
+ RecordGrantInput,
11
+ RevokeGrantInput,
12
+ } from '../domain/grant';
13
+ import type { ScopeRef } from '../domain/scope';
14
+
15
+ export const DEFAULT_GRANT_MINUTES = 30 * 24 * 60;
16
+ const MAX_GRANT_MINUTES = 90 * 24 * 60;
17
+
18
+ interface GrantStoreData {
19
+ schemaVersion: 1;
20
+ grants: Grant[];
21
+ }
22
+
23
+ const RISK_RANK: Record<string, number> = {
24
+ readonly: 0,
25
+ workspace_write: 1,
26
+ remote_write: 2,
27
+ destructive: 3,
28
+ };
29
+
30
+ export function canonicalGrantStorePath(controllerHome: string): string {
31
+ return join(resolve(controllerHome), 'system', 'authorization-grants', 'grants.json');
32
+ }
33
+
34
+ const GRANT_RISKS = new Set(['readonly', 'workspace_write', 'remote_write', 'destructive']);
35
+ const SCOPE_KINDS = new Set(['workspace', 'project', 'requirement', 'plan', 'plan_step', 'work']);
36
+
37
+ function validateGrantTarget(value: unknown, label: string): GrantTarget | undefined {
38
+ if (value === undefined) return undefined;
39
+ if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(`${label} must be an object`);
40
+ const target = value as Record<string, unknown>;
41
+ const kind = typeof target.kind === 'string' ? target.kind.trim() : '';
42
+ const id = typeof target.id === 'string' ? target.id.trim() : '';
43
+ if (!kind || !id) throw new Error(`${label}.kind/id are required`);
44
+ const optionalString = (field: 'repoId' | 'identityFingerprint') => {
45
+ const current = target[field];
46
+ if (current === undefined) return undefined;
47
+ if (typeof current !== 'string' || !current.trim()) throw new Error(`${label}.${field} is invalid`);
48
+ return current.trim();
49
+ };
50
+ let scopeRef: GrantTarget['scopeRef'];
51
+ if (target.scopeRef !== undefined) {
52
+ if (!target.scopeRef || typeof target.scopeRef !== 'object' || Array.isArray(target.scopeRef)) throw new Error(`${label}.scopeRef is invalid`);
53
+ const scope = target.scopeRef as Record<string, unknown>;
54
+ const scopeKind = typeof scope.kind === 'string' ? scope.kind.trim() : '';
55
+ const scopeId = typeof scope.id === 'string' ? scope.id.trim() : '';
56
+ if (scope.schemaVersion !== 1 || !SCOPE_KINDS.has(scopeKind) || !scopeId) throw new Error(`${label}.scopeRef is invalid`);
57
+ scopeRef = { schemaVersion: 1, kind: scopeKind as ScopeRef['kind'], id: scopeId };
58
+ }
59
+ const repoId = optionalString('repoId');
60
+ const identityFingerprint = optionalString('identityFingerprint');
61
+ return { kind, id, ...(repoId ? { repoId } : {}), ...(scopeRef ? { scopeRef } : {}), ...(identityFingerprint ? { identityFingerprint } : {}) };
62
+ }
63
+
64
+ function validatePersistedGrant(value: unknown, index: number): Grant {
65
+ if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(`grants[${index}] must be an object`);
66
+ const row = value as Record<string, unknown>;
67
+ const requiredString = (field: string) => {
68
+ const current = row[field];
69
+ if (typeof current !== 'string' || !current.trim()) throw new Error(`grants[${index}].${field} is invalid`);
70
+ return current.trim();
71
+ };
72
+ if (row.schemaVersion !== 1) throw new Error(`grants[${index}].schemaVersion is invalid`);
73
+ if (!Array.isArray(row.capabilities) || row.capabilities.some((entry) => typeof entry !== 'string' || !entry.trim())) throw new Error(`grants[${index}].capabilities is invalid`);
74
+ if (row.scopes !== undefined && (!Array.isArray(row.scopes) || row.scopes.some((entry) => typeof entry !== 'string' || !entry.trim()))) throw new Error(`grants[${index}].scopes is invalid`);
75
+ if (row.riskCeiling !== undefined && (typeof row.riskCeiling !== 'string' || !GRANT_RISKS.has(row.riskCeiling))) throw new Error(`grants[${index}].riskCeiling is invalid`);
76
+ const createdAt = requiredString('createdAt');
77
+ const updatedAt = requiredString('updatedAt');
78
+ const expiresAt = requiredString('expiresAt');
79
+ if (![createdAt, updatedAt, expiresAt].every((timestamp) => Number.isFinite(Date.parse(timestamp)))) throw new Error(`grants[${index}] timestamps are invalid`);
80
+ const revokedAt = row.revokedAt;
81
+ if (revokedAt !== undefined && (typeof revokedAt !== 'string' || !Number.isFinite(Date.parse(revokedAt)))) throw new Error(`grants[${index}].revokedAt is invalid`);
82
+ if (row.revokedReason !== undefined && typeof row.revokedReason !== 'string') throw new Error(`grants[${index}].revokedReason is invalid`);
83
+ if (row.ownerScope !== undefined && (typeof row.ownerScope !== 'string' || !row.ownerScope.trim())) throw new Error(`grants[${index}].ownerScope is invalid`);
84
+ if (row.constraints !== undefined && (!row.constraints || typeof row.constraints !== 'object' || Array.isArray(row.constraints))) throw new Error(`grants[${index}].constraints is invalid`);
85
+ const target = validateGrantTarget(row.target, `grants[${index}].target`);
86
+ return {
87
+ schemaVersion: 1,
88
+ grantId: requiredString('grantId'),
89
+ principalId: requiredString('principalId'),
90
+ ...(typeof row.ownerScope === 'string' && row.ownerScope.trim() ? { ownerScope: row.ownerScope.trim() } : {}),
91
+ capabilities: [...new Set((row.capabilities as string[]).map((entry) => entry.trim()))].sort(),
92
+ ...(target ? { target } : {}),
93
+ ...(Array.isArray(row.scopes) ? { scopes: [...new Set((row.scopes as string[]).map((entry) => entry.trim()))].sort() } : {}),
94
+ ...(typeof row.riskCeiling === 'string' ? { riskCeiling: row.riskCeiling as Grant['riskCeiling'] } : {}),
95
+ ...(row.constraints && typeof row.constraints === 'object' && !Array.isArray(row.constraints) ? { constraints: row.constraints as Record<string, unknown> } : {}),
96
+ createdAt,
97
+ updatedAt,
98
+ expiresAt,
99
+ ...(typeof revokedAt === 'string' ? { revokedAt } : {}),
100
+ ...(typeof row.revokedReason === 'string' ? { revokedReason: row.revokedReason } : {}),
101
+ };
102
+ }
103
+
104
+ function loadStore(controllerHome: string): GrantStoreData {
105
+ const path = canonicalGrantStorePath(controllerHome);
106
+ if (!existsSync(path)) return { schemaVersion: 1, grants: [] };
107
+ try {
108
+ const raw = JSON.parse(readFileSync(path, 'utf8'));
109
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw)) throw new Error('store must be an object');
110
+ const record = raw as Record<string, unknown>;
111
+ if (record.schemaVersion !== 1 || !Array.isArray(record.grants)) throw new Error('schemaVersion/grants are invalid');
112
+ return { schemaVersion: 1, grants: record.grants.map(validatePersistedGrant) };
113
+ } catch (error) {
114
+ throw new Error(`CANONICAL_GRANT_STORE_CORRUPT: ${path}: ${error instanceof Error ? error.message : String(error)}`);
115
+ }
116
+ }
117
+
118
+ function saveStore(controllerHome: string, store: GrantStoreData): void {
119
+ const path = canonicalGrantStorePath(controllerHome);
120
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
121
+ const temporary = `${path}.${process.pid}.${randomUUID().slice(0, 8)}.tmp`;
122
+ writeFileSync(temporary, `${JSON.stringify(store, null, 2)}\n`, 'utf8');
123
+ renameSync(temporary, path);
124
+ }
125
+
126
+ function targetMatches(left?: GrantTarget, right?: GrantTarget): boolean {
127
+ if (!left && !right) return true;
128
+ if (!left || !right) return false;
129
+ const scopeMatch = (!left.scopeRef && !right.scopeRef)
130
+ || Boolean(left.scopeRef && right.scopeRef
131
+ && left.scopeRef.schemaVersion === right.scopeRef.schemaVersion
132
+ && left.scopeRef.kind === right.scopeRef.kind
133
+ && left.scopeRef.id === right.scopeRef.id);
134
+ return left.kind === right.kind
135
+ && left.id === right.id
136
+ && left.repoId === right.repoId
137
+ && left.identityFingerprint === right.identityFingerprint
138
+ && scopeMatch;
139
+ }
140
+
141
+ function scopesContain(granted: readonly string[] = [], requested: readonly string[] = []): boolean {
142
+ const available = new Set(granted);
143
+ return requested.every((scope) => available.has(scope));
144
+ }
145
+
146
+ function capabilityMatches(grantedCapabilities: readonly string[], requested: string): boolean {
147
+ if (grantedCapabilities.includes('*') || grantedCapabilities.includes(requested)) return true;
148
+ if (requested.includes(':')) {
149
+ const prefix = requested.split(':')[0] + ':*';
150
+ if (grantedCapabilities.includes(prefix)) return true;
151
+ }
152
+ return false;
153
+ }
154
+
155
+ export function recordCanonicalGrant(controllerHome: string, input: RecordGrantInput): Grant {
156
+ const now = input.now ?? new Date();
157
+ const timestamp = now.toISOString();
158
+ const expiresInMinutes = Math.min(
159
+ Math.max(1, Math.trunc(input.expiresInMinutes ?? DEFAULT_GRANT_MINUTES)),
160
+ MAX_GRANT_MINUTES,
161
+ );
162
+ const grantId = input.grantId?.trim() || `grant_${randomUUID().replaceAll('-', '')}`;
163
+ const grant: Grant = {
164
+ schemaVersion: 1,
165
+ grantId,
166
+ principalId: input.principalId.trim(),
167
+ ...(input.ownerScope?.trim() ? { ownerScope: input.ownerScope.trim() } : {}),
168
+ capabilities: [...new Set(input.capabilities.map((c) => c.trim()).filter(Boolean))].sort(),
169
+ ...(input.target ? { target: input.target } : {}),
170
+ ...(input.scopes ? { scopes: [...new Set(input.scopes.map((s) => s.trim()).filter(Boolean))].sort() } : {}),
171
+ ...(input.riskCeiling ? { riskCeiling: input.riskCeiling } : {}),
172
+ ...(input.constraints ? { constraints: input.constraints } : {}),
173
+ createdAt: timestamp,
174
+ updatedAt: timestamp,
175
+ expiresAt: new Date(now.getTime() + expiresInMinutes * 60_000).toISOString(),
176
+ };
177
+
178
+ const store = loadStore(controllerHome);
179
+ store.grants = store.grants.filter((entry) => {
180
+ if (entry.grantId === grantId) return false;
181
+ const samePrincipal = entry.principalId === grant.principalId;
182
+ const sameOwner = entry.ownerScope === grant.ownerScope;
183
+ const sameTarget = targetMatches(entry.target, grant.target);
184
+ const sameCapabilities = entry.capabilities.length === grant.capabilities.length
185
+ && entry.capabilities.every((c, i) => c === grant.capabilities[i]);
186
+ return !(samePrincipal && sameOwner && sameTarget && sameCapabilities);
187
+ });
188
+ store.grants.push(grant);
189
+ saveStore(controllerHome, store);
190
+ return grant;
191
+ }
192
+
193
+ export function revokeCanonicalGrant(controllerHome: string, input: RevokeGrantInput): Grant {
194
+ const grantId = input.grantId.trim();
195
+ const now = input.now ?? new Date();
196
+ const store = loadStore(controllerHome);
197
+ const index = store.grants.findIndex((g) => g.grantId === grantId);
198
+ if (index < 0) throw new Error(`GRANT_NOT_FOUND: ${grantId}`);
199
+ const current = store.grants[index]!;
200
+ if (input.ownerScope && current.ownerScope && current.ownerScope !== input.ownerScope.trim()) {
201
+ throw new Error(`GRANT_OWNER_MISMATCH: ${grantId}`);
202
+ }
203
+ const revoked: Grant = {
204
+ ...current,
205
+ updatedAt: now.toISOString(),
206
+ revokedAt: now.toISOString(),
207
+ revokedReason: input.reason.trim(),
208
+ };
209
+ store.grants[index] = revoked;
210
+ saveStore(controllerHome, store);
211
+ return revoked;
212
+ }
213
+
214
+ export function findActiveCanonicalGrant(controllerHome: string, query: QueryGrantInput): Grant | undefined {
215
+ const store = loadStore(controllerHome);
216
+ const nowMs = (query.at ?? new Date()).getTime();
217
+ const requestedRiskRank = RISK_RANK[query.risk ?? 'readonly'] ?? 0;
218
+
219
+ for (const grant of store.grants) {
220
+ if (grant.revokedAt) continue;
221
+ if (Date.parse(grant.expiresAt) <= nowMs) continue;
222
+ if (query.principalId && grant.principalId !== query.principalId.trim()) continue;
223
+ if (query.ownerScope && grant.ownerScope && grant.ownerScope !== query.ownerScope.trim()) continue;
224
+ if (!capabilityMatches(grant.capabilities, query.capability)) continue;
225
+ if (query.target && !targetMatches(grant.target, query.target)) continue;
226
+ if (query.scopes && !scopesContain(grant.scopes, query.scopes)) continue;
227
+ if (grant.riskCeiling) {
228
+ const grantRiskRank = RISK_RANK[grant.riskCeiling] ?? 0;
229
+ if (grantRiskRank < requestedRiskRank) continue;
230
+ }
231
+ return structuredClone(grant);
232
+ }
233
+ return undefined;
234
+ }
235
+
236
+ export function listCanonicalGrants(controllerHome: string, filter?: { principalId?: string; ownerScope?: string }): Grant[] {
237
+ const store = loadStore(controllerHome);
238
+ return store.grants
239
+ .filter((grant) => {
240
+ if (filter?.principalId && grant.principalId !== filter.principalId.trim()) return false;
241
+ if (filter?.ownerScope && grant.ownerScope !== filter.ownerScope.trim()) return false;
242
+ return true;
243
+ })
244
+ .map((grant) => structuredClone(grant));
245
+ }
246
+
247
+ export function reconcileCanonicalGrants(controllerHome: string, input: ReconcileGrantsInput = {}): ReconcileGrantsResult {
248
+ const retiredOwnerScopes = new Set((input.retiredOwnerScopes ?? []).map((s) => s.trim()).filter(Boolean));
249
+ const nowMs = (input.now ?? new Date()).getTime();
250
+ const store = loadStore(controllerHome);
251
+ let removedRetiredOwner = 0;
252
+ let removedRevoked = 0;
253
+ let removedExpired = 0;
254
+
255
+ const grants = store.grants.filter((grant) => {
256
+ if (grant.ownerScope && retiredOwnerScopes.has(grant.ownerScope)) {
257
+ removedRetiredOwner += 1;
258
+ return false;
259
+ }
260
+ if (grant.revokedAt) {
261
+ removedRevoked += 1;
262
+ return false;
263
+ }
264
+ if (Date.parse(grant.expiresAt) <= nowMs) {
265
+ removedExpired += 1;
266
+ return false;
267
+ }
268
+ return true;
269
+ });
270
+
271
+ const removedTotal = removedRetiredOwner + removedRevoked + removedExpired;
272
+ if (removedTotal > 0) {
273
+ store.grants = grants;
274
+ saveStore(controllerHome, store);
275
+ }
276
+ return {
277
+ removedRetiredOwner,
278
+ removedRevoked,
279
+ removedExpired,
280
+ removedTotal,
281
+ remaining: grants.length,
282
+ changed: removedTotal > 0,
283
+ };
284
+ }
@@ -0,0 +1,259 @@
1
+ import { createHash, randomUUID } from 'crypto';
2
+ import { existsSync, lstatSync, mkdirSync, readFileSync, realpathSync, renameSync, writeFileSync, readdirSync } from 'fs';
3
+ import { dirname, join, resolve } from 'path';
4
+ import {
5
+ ownedResourceLocator,
6
+ type OwnedResource,
7
+ type OwnedResourceKind,
8
+ type OwnedResourceLocator,
9
+ type RecordOwnedResourceInput,
10
+ } from '../domain/owned-resource';
11
+ import { ensureForgeInstanceIdentity } from './identity-store';
12
+
13
+ function resourcesDir(controllerHome: string): string {
14
+ const dir = resolve(controllerHome, 'owned-resources');
15
+ if (!existsSync(dir)) {
16
+ mkdirSync(dir, { recursive: true });
17
+ }
18
+ return dir;
19
+ }
20
+
21
+ function resourcePath(controllerHome: string, resourceId: string): string {
22
+ const sanitized = resourceId.replace(/[^a-zA-Z0-9._-]/g, '_');
23
+ return join(resourcesDir(controllerHome), `${sanitized}.json`);
24
+ }
25
+
26
+ function validateOwnedResource(value: unknown): OwnedResource {
27
+ if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error('record must be an object');
28
+ const resource = value as OwnedResource;
29
+ if (resource.schemaVersion !== 1 || !resource.resourceId || !resource.kind || !resource.targetRef) {
30
+ throw new Error('required resource identity is missing');
31
+ }
32
+ if (!resource.provenance?.creator || !resource.provenance.createdAt || !resource.retention?.intent || !resource.status || !resource.updatedAt) {
33
+ throw new Error('required ownership metadata is missing');
34
+ }
35
+ if (resource.cleanupCapable === true
36
+ && (!resource.ownerForgeInstanceId || !resource.locator?.kind || !resource.locator.value || !resource.identityFingerprint)) {
37
+ throw new Error('cleanup-capable resource lacks owner/locator/fingerprint');
38
+ }
39
+ return resource;
40
+ }
41
+
42
+ function readResourceFile(filePath: string): OwnedResource | undefined {
43
+ if (!existsSync(filePath)) return undefined;
44
+ try {
45
+ return validateOwnedResource(JSON.parse(readFileSync(filePath, 'utf8')));
46
+ } catch (error) {
47
+ throw new Error(`OWNED_RESOURCE_STORE_CORRUPT: ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
48
+ }
49
+ }
50
+
51
+ function writeResourceFile(controllerHome: string, resource: OwnedResource): void {
52
+ const filePath = resourcePath(controllerHome, resource.resourceId);
53
+ const tmpPath = `${filePath}.${randomUUID()}.tmp`;
54
+ writeFileSync(tmpPath, JSON.stringify(resource, null, 2), 'utf8');
55
+ renameSync(tmpPath, filePath);
56
+ }
57
+
58
+ export function ownedResourceLocatorFingerprint(ownerForgeInstanceId: string, locator: OwnedResourceLocator): string {
59
+ const owner = ownerForgeInstanceId.trim();
60
+ if (!owner || !locator.kind || !locator.value.trim()) throw new Error('OWNED_RESOURCE_FINGERPRINT_IDENTITY_REQUIRED');
61
+ return createHash('sha256').update(`${owner}\0${locator.kind}\0${locator.value.trim()}`).digest('hex');
62
+ }
63
+
64
+ export function ownedFilesystemIdentityFingerprint(ownerForgeInstanceId: string, pathInput: string): string {
65
+ const path = resolve(pathInput);
66
+ if (!existsSync(path)) throw new Error(`OWNED_RESOURCE_FILESYSTEM_TARGET_MISSING: ${path}`);
67
+ const canonicalPath = realpathSync(path);
68
+ const stat = lstatSync(canonicalPath);
69
+ const kind = stat.isDirectory() ? 'directory' : stat.isFile() ? 'file' : stat.isSymbolicLink() ? 'symlink' : 'other';
70
+ return createHash('sha256').update([
71
+ ownerForgeInstanceId.trim(),
72
+ 'filesystem_path',
73
+ canonicalPath,
74
+ String(stat.dev),
75
+ String(stat.ino),
76
+ kind,
77
+ ].join('\0')).digest('hex');
78
+ }
79
+
80
+ function resolvedIdentityFingerprint(
81
+ ownerForgeInstanceId: string,
82
+ locator: OwnedResourceLocator,
83
+ explicitFingerprint?: string,
84
+ ): string {
85
+ const explicit = explicitFingerprint?.trim();
86
+ if (explicit) return explicit;
87
+ if (locator.kind === 'filesystem_path') return ownedFilesystemIdentityFingerprint(ownerForgeInstanceId, locator.value);
88
+ return ownedResourceLocatorFingerprint(ownerForgeInstanceId, locator);
89
+ }
90
+
91
+ export interface OwnedResourceCleanupTargetInput {
92
+ resourceId: string;
93
+ kind: OwnedResourceKind;
94
+ targetRef?: string;
95
+ locator?: OwnedResourceLocator;
96
+ identityFingerprint?: string;
97
+ }
98
+
99
+ /**
100
+ * Cleanup authorization is an exact OwnedResource fact, never path shape or caller possession.
101
+ * Filesystem targets are re-fingerprinted immediately before mutation so a recycled path cannot
102
+ * inherit an older Forge ownership record.
103
+ */
104
+ export function assertOwnedResourceCleanupTarget(
105
+ controllerHome: string,
106
+ input: OwnedResourceCleanupTargetInput,
107
+ ): OwnedResource {
108
+ const resource = getOwnedResource(controllerHome, input.resourceId);
109
+ if (!resource) throw new Error(`OWNED_RESOURCE_CLEANUP_AUTHORITY_MISSING: ${input.resourceId}`);
110
+ const currentInstance = ensureForgeInstanceIdentity({ controllerHome }).instanceId;
111
+ if (resource.ownerForgeInstanceId !== currentInstance) {
112
+ throw new Error(`OWNED_RESOURCE_OWNER_INSTANCE_MISMATCH: ${input.resourceId}`);
113
+ }
114
+ if (resource.cleanupCapable !== true) throw new Error(`OWNED_RESOURCE_NOT_CLEANUP_CAPABLE: ${input.resourceId}`);
115
+ if (resource.status === 'released') throw new Error(`OWNED_RESOURCE_ALREADY_RELEASED: ${input.resourceId}`);
116
+ if (resource.kind !== input.kind) throw new Error(`OWNED_RESOURCE_KIND_MISMATCH: ${input.resourceId}`);
117
+ if (input.targetRef?.trim() && resource.targetRef !== input.targetRef.trim()) {
118
+ throw new Error(`OWNED_RESOURCE_TARGET_MISMATCH: ${input.resourceId}`);
119
+ }
120
+ if (!resource.locator || !resource.identityFingerprint) throw new Error(`OWNED_RESOURCE_CLEANUP_IDENTITY_MISSING: ${input.resourceId}`);
121
+ const expectedLocator = input.locator ?? resource.locator;
122
+ if (expectedLocator.kind !== resource.locator.kind || expectedLocator.value.trim() !== resource.locator.value) {
123
+ throw new Error(`OWNED_RESOURCE_LOCATOR_MISMATCH: ${input.resourceId}`);
124
+ }
125
+ const observedFingerprint = input.identityFingerprint?.trim()
126
+ || (resource.locator.kind === 'filesystem_path'
127
+ ? ownedFilesystemIdentityFingerprint(currentInstance, resource.locator.value)
128
+ : ownedResourceLocatorFingerprint(currentInstance, expectedLocator));
129
+ if (observedFingerprint !== resource.identityFingerprint) {
130
+ throw new Error(`OWNED_RESOURCE_IDENTITY_FINGERPRINT_MISMATCH: ${input.resourceId}`);
131
+ }
132
+ return resource;
133
+ }
134
+
135
+ export function recordOwnedResource(controllerHome: string, input: RecordOwnedResourceInput): OwnedResource {
136
+ const now = new Date().toISOString();
137
+ const resourceId = input.resourceId || `res-${randomUUID()}`;
138
+ // Cleanup authority is target-safe: ownership is pinned to the ForgeInstance
139
+ // that created/adopted the resource, and the locator fingerprint follows the
140
+ // resource kind so a recycled path/id cannot be reclaimed as the same resource.
141
+ const ownerForgeInstanceId = input.ownerForgeInstanceId?.trim()
142
+ || ensureForgeInstanceIdentity({ controllerHome }).instanceId;
143
+ const locator = input.locator ?? ownedResourceLocator(input.kind, input.targetRef);
144
+ const identityFingerprint = resolvedIdentityFingerprint(ownerForgeInstanceId, locator, input.identityFingerprint);
145
+ const cleanupCapable = input.cleanupCapable ?? true;
146
+ const existing = readResourceFile(resourcePath(controllerHome, resourceId));
147
+ if (existing) {
148
+ const sameLocator = existing.kind === input.kind
149
+ && existing.ownerForgeInstanceId === ownerForgeInstanceId
150
+ && existing.locator?.kind === locator.kind
151
+ && existing.locator?.value === locator.value;
152
+ const sameIdentity = sameLocator && existing.identityFingerprint === identityFingerprint;
153
+ const legacyWeakFilesystemFingerprint = sameLocator
154
+ && locator.kind === 'filesystem_path'
155
+ && existing.identityFingerprint === ownedResourceLocatorFingerprint(ownerForgeInstanceId, locator)
156
+ && existing.identityFingerprint !== identityFingerprint;
157
+ if (legacyWeakFilesystemFingerprint) {
158
+ // Never bless a pre-upgrade path-only fingerprint as the identity of the
159
+ // currently observed inode. Preserve the historical record but retire its
160
+ // destructive authority; a newly created resource gets a new strong witness.
161
+ const downgraded: OwnedResource = { ...existing, cleanupCapable: false, updatedAt: now };
162
+ writeResourceFile(controllerHome, downgraded);
163
+ return downgraded;
164
+ }
165
+ if (!sameIdentity) throw new Error(`OWNED_RESOURCE_IDENTITY_CONFLICT: ${resourceId}`);
166
+ if (existing.cleanupCapable !== true && cleanupCapable === true) {
167
+ throw new Error(`OWNED_RESOURCE_CLEANUP_AUTHORITY_ESCALATION_FORBIDDEN: ${resourceId}`);
168
+ }
169
+ if (existing.status === 'released') throw new Error(`OWNED_RESOURCE_REUSE_REQUIRES_NEW_ID: ${resourceId}`);
170
+ }
171
+ const resource: OwnedResource = {
172
+ schemaVersion: 1,
173
+ resourceId,
174
+ kind: input.kind,
175
+ targetRef: input.targetRef,
176
+ ownerForgeInstanceId,
177
+ locator,
178
+ identityFingerprint,
179
+ cleanupCapable,
180
+ provenance: {
181
+ creator: input.creator,
182
+ createdAt: now,
183
+ associatedWorkId: input.associatedWorkId,
184
+ associatedRequirementId: input.associatedRequirementId,
185
+ repoId: input.repoId,
186
+ },
187
+ retention: {
188
+ intent: input.retentionIntent ?? 'temporary',
189
+ expiresAt: input.expiresAt,
190
+ },
191
+ status: 'active',
192
+ updatedAt: now,
193
+ };
194
+
195
+ writeResourceFile(controllerHome, resource);
196
+ return resource;
197
+ }
198
+
199
+ export function getOwnedResource(controllerHome: string, resourceId: string): OwnedResource | undefined {
200
+ return readResourceFile(resourcePath(controllerHome, resourceId));
201
+ }
202
+
203
+ export function listOwnedResources(controllerHome: string, filter?: { kind?: string; status?: string; repoId?: string }): OwnedResource[] {
204
+ const dir = resourcesDir(controllerHome);
205
+ const files = readdirSync(dir).filter((f) => f.endsWith('.json'));
206
+ const results: OwnedResource[] = [];
207
+
208
+ for (const file of files) {
209
+ const resource = readResourceFile(join(dir, file));
210
+ if (!resource) continue;
211
+ if (filter?.kind && resource.kind !== filter.kind) continue;
212
+ if (filter?.status && resource.status !== filter.status) continue;
213
+ if (filter?.repoId && resource.provenance.repoId !== filter.repoId) continue;
214
+ results.push(resource);
215
+ }
216
+
217
+ return results.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
218
+ }
219
+
220
+ /** Mark an owned resource as intentionally retained without changing cleanup authority. */
221
+ export function markOwnedResourceRetained(
222
+ controllerHome: string,
223
+ resourceId: string,
224
+ ): OwnedResource | undefined {
225
+ const existing = getOwnedResource(controllerHome, resourceId);
226
+ if (!existing) return undefined;
227
+ const updated: OwnedResource = {
228
+ ...existing,
229
+ status: 'retained',
230
+ updatedAt: new Date().toISOString(),
231
+ };
232
+ writeResourceFile(controllerHome, updated);
233
+ return updated;
234
+ }
235
+
236
+ export function markOwnedResourceCleaned(
237
+ controllerHome: string,
238
+ resourceId: string,
239
+ cleanedBy: string,
240
+ receiptRef?: string,
241
+ ): OwnedResource | undefined {
242
+ const existing = getOwnedResource(controllerHome, resourceId);
243
+ if (!existing) return undefined;
244
+
245
+ const now = new Date().toISOString();
246
+ const updated: OwnedResource = {
247
+ ...existing,
248
+ status: 'released',
249
+ updatedAt: now,
250
+ cleanupProof: {
251
+ cleanedAt: now,
252
+ cleanedBy,
253
+ receiptRef,
254
+ },
255
+ };
256
+
257
+ writeResourceFile(controllerHome, updated);
258
+ return updated;
259
+ }