@moretea-labs/forge 1.7.2 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (900) hide show
  1. package/AGENTS.md +121 -62
  2. package/CHANGELOG.md +40 -0
  3. package/CLAUDE.md +57 -62
  4. package/CONTRIBUTING.md +3 -2
  5. package/README.md +2 -2
  6. package/SKILL.md +0 -1
  7. package/THIRD_PARTY_NOTICES.md +5 -2
  8. package/adapters/browser/index.ts +2 -0
  9. package/adapters/chatgpt/browser-delivery-host.ts +77 -0
  10. package/adapters/chatgpt/browser-delivery-runtime.ts +1256 -0
  11. package/adapters/chatgpt/controller-binding-store.ts +134 -0
  12. package/adapters/chatgpt/controller-round-host.ts +68 -0
  13. package/adapters/chatgpt/controller-round-settlement-store.ts +99 -0
  14. package/adapters/chatgpt/provider-delivery.ts +340 -0
  15. package/adapters/chatgpt/work-conversation-binding-store.ts +218 -0
  16. package/adapters/chatgpt/wsl-bridge-delivery-host.ts +63 -0
  17. package/adapters/computer/chatgpt-extension-target.ts +463 -0
  18. package/adapters/computer/chatgpt-target-router.ts +103 -0
  19. package/adapters/computer/chrome-extension/background.js +385 -0
  20. package/adapters/computer/chrome-extension/content.js +378 -0
  21. package/adapters/computer/chrome-extension/core.js +24 -0
  22. package/adapters/computer/chrome-extension/manifest.json +30 -0
  23. package/adapters/computer/desktop-operator-contract.ts +7 -0
  24. package/adapters/computer/desktop-operator-discovery.ts +181 -0
  25. package/adapters/computer/desktop-operator-negotiation.ts +174 -0
  26. package/adapters/computer/desktop-operator-provider.ts +312 -0
  27. package/adapters/computer/index.ts +1 -0
  28. package/adapters/computer/interaction-target-authority.ts +1068 -0
  29. package/adapters/controller-process/binding-store.ts +34 -0
  30. package/adapters/controller-process/controller-host.ts +26 -0
  31. package/adapters/mcp/access-mode.ts +132 -0
  32. package/adapters/mcp/audit.ts +32 -0
  33. package/adapters/mcp/auth.ts +406 -0
  34. package/adapters/mcp/instructions.ts +37 -0
  35. package/adapters/mcp/legacy-context.ts +18 -0
  36. package/adapters/mcp/multi-repository.ts +421 -0
  37. package/adapters/mcp/oauth.ts +464 -0
  38. package/adapters/mcp/paths.ts +143 -0
  39. package/adapters/mcp/policy.ts +232 -0
  40. package/adapters/mcp/proxy-env.ts +62 -0
  41. package/adapters/mcp/readiness-projection.ts +24 -0
  42. package/adapters/mcp/redaction.ts +21 -0
  43. package/adapters/mcp/repo.ts +24 -0
  44. package/adapters/mcp/runtime-gateway/artifact-adapter.ts +52 -0
  45. package/adapters/mcp/runtime-gateway/automation-receipt-adapter.ts +87 -0
  46. package/adapters/mcp/runtime-gateway/bounded-result-runtime.ts +62 -0
  47. package/adapters/mcp/runtime-gateway/cognition-settlement.ts +201 -0
  48. package/adapters/mcp/runtime-gateway/context-adapter.ts +1167 -0
  49. package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +91 -0
  50. package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +206 -0
  51. package/adapters/mcp/runtime-gateway/core-capability-adapter.ts +258 -0
  52. package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +130 -0
  53. package/adapters/mcp/runtime-gateway/engineering-tool-contract.ts +15 -0
  54. package/adapters/mcp/runtime-gateway/execution-control-adapter.ts +28 -0
  55. package/adapters/mcp/runtime-gateway/execution-tools.ts +173 -0
  56. package/adapters/mcp/runtime-gateway/filesystem-adapter.ts +38 -0
  57. package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +412 -0
  58. package/adapters/mcp/runtime-gateway/legacy-ios-tool-adapter.ts +105 -0
  59. package/adapters/mcp/runtime-gateway/maintenance-adapter.ts +44 -0
  60. package/adapters/mcp/runtime-gateway/model-adapter.ts +63 -0
  61. package/adapters/mcp/runtime-gateway/persisted-check-process.ts +3 -0
  62. package/adapters/mcp/runtime-gateway/plugin-adapter.ts +380 -0
  63. package/adapters/mcp/runtime-gateway/process-tools.ts +457 -0
  64. package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +88 -0
  65. package/adapters/mcp/runtime-gateway/recovery-adapter.ts +285 -0
  66. package/adapters/mcp/runtime-gateway/recovery-client-adapter.ts +70 -0
  67. package/adapters/mcp/runtime-gateway/recovery-tool-contract.ts +99 -0
  68. package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +79 -0
  69. package/adapters/mcp/runtime-gateway/result-adapter.ts +114 -0
  70. package/adapters/mcp/runtime-gateway/router.ts +242 -0
  71. package/adapters/mcp/runtime-gateway/routing-policy.ts +499 -0
  72. package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +1200 -0
  73. package/adapters/mcp/runtime-gateway/runtime-readiness-observation.ts +218 -0
  74. package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +574 -0
  75. package/adapters/mcp/runtime-gateway/runtime-tool-shared.ts +27 -0
  76. package/adapters/mcp/runtime-gateway/runtime-tools.ts +78 -0
  77. package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +187 -0
  78. package/adapters/mcp/runtime-gateway/shared-adapter.ts +45 -0
  79. package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +962 -0
  80. package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +136 -0
  81. package/adapters/mcp/runtime-gateway/work-adapter.ts +325 -0
  82. package/adapters/mcp/runtime-gateway/work-controller-operations.ts +257 -0
  83. package/adapters/mcp/runtime-gateway/work-detail-projection.ts +60 -0
  84. package/adapters/mcp/runtime-gateway/work-input-wire-migration.ts +246 -0
  85. package/adapters/mcp/runtime-gateway/work-learning-operations.ts +145 -0
  86. package/adapters/mcp/runtime-gateway/work-list-projection.ts +38 -0
  87. package/adapters/mcp/runtime-gateway/work-plan-operations.ts +382 -0
  88. package/adapters/mcp/runtime-gateway/work-repair-adapter.ts +308 -0
  89. package/adapters/mcp/runtime-gateway/work-requirement-operations.ts +148 -0
  90. package/adapters/mcp/runtime-gateway/work-semantic-operations.ts +263 -0
  91. package/adapters/mcp/runtime-gateway/work-validation-reconciler.ts +1 -0
  92. package/adapters/mcp/runtime-gateway/work-workflow-operations.ts +113 -0
  93. package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +156 -0
  94. package/adapters/mcp/server.ts +1092 -0
  95. package/adapters/mcp/setup.ts +789 -0
  96. package/adapters/mcp/tool-capability-cache.ts +87 -0
  97. package/adapters/mcp/tool-mapping/access-tools.ts +387 -0
  98. package/adapters/mcp/tool-mapping/legacy-tool-service.ts +5139 -0
  99. package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +145 -0
  100. package/adapters/mcp/tool-mapping/repository-tools.ts +1682 -0
  101. package/adapters/mcp/tool-mapping/tools.ts +9 -0
  102. package/adapters/mcp/tool-mapping/umbrella-tools.ts +117 -0
  103. package/adapters/mcp/toolset-names.ts +79 -0
  104. package/adapters/mcp/toolset-selection.ts +41 -0
  105. package/adapters/mcp/toolset.ts +337 -0
  106. package/adapters/mcp/transports/http-observation.ts +365 -0
  107. package/adapters/mcp/transports/http.ts +933 -0
  108. package/adapters/mcp/transports/oauth-http.ts +322 -0
  109. package/adapters/mcp/transports/session-registry.ts +519 -0
  110. package/adapters/mcp/transports/stdio.ts +8 -0
  111. package/adapters/mcp/tunnels/openai-secure-tunnel.ts +223 -0
  112. package/adapters/mcp/types.ts +41 -0
  113. package/assets/AGENTS.md +2 -16
  114. package/assets/CLAUDE.md +2 -16
  115. package/assets/hooks/AGENTS.md +3 -14
  116. package/assets/hooks/CLAUDE.md +3 -14
  117. package/assets/hooks/hook-input.sh +9 -2
  118. package/assets/hooks/lib/workflow-state.sh +28 -10
  119. package/assets/hooks/prompt-guard.sh +63 -37
  120. package/assets/hooks/security-sentinel.sh +2 -1
  121. package/assets/hooks/session-start-context.sh +7 -5
  122. package/assets/hooks/stop-orchestrator.sh +13 -3
  123. package/assets/initializer-question-pack.v4.json +11 -7
  124. package/assets/partials/05-workflow.partial.md +18 -73
  125. package/assets/partials/07-footer.partial.md +1 -1
  126. package/assets/partials-agents/02-operating-mode.partial.md +1 -2
  127. package/assets/partials-agents/04-task-protocol.partial.md +14 -59
  128. package/assets/partials-agents/06-quality-safety.partial.md +11 -16
  129. package/assets/partials-agents/08-deep-docs.partial.md +1 -2
  130. package/assets/plan-map.json +11 -11
  131. package/assets/plugin-registry.v1.json +11 -3
  132. package/assets/plugin-trust-policy.v1.json +6 -0
  133. package/assets/recovery/ForgeRecovery.ps1 +100 -0
  134. package/assets/recovery/forge-wsl-rescue +271 -0
  135. package/assets/reference-configs/agentic-development-flow.md +25 -0
  136. package/assets/reference-configs/development-protocol.md +11 -15
  137. package/assets/reference-configs/document-generation.md +1 -1
  138. package/assets/reference-configs/global-working-rules.md +28 -1
  139. package/assets/reference-configs/harness-overview.md +22 -112
  140. package/assets/reference-configs/hook-operations.md +1 -1
  141. package/assets/reference-configs/sprint-contracts.md +2 -2
  142. package/assets/skill-version.json +2 -2
  143. package/assets/templates/helpers/architecture-event.ts +3 -34
  144. package/assets/templates/helpers/architecture-queue.sh +61 -10
  145. package/assets/templates/helpers/archive-workflow.sh +90 -180
  146. package/assets/templates/helpers/capability-config.ts +8 -11
  147. package/assets/templates/helpers/capability-resolver.ts +37 -19
  148. package/assets/templates/helpers/capture-plan.sh +2 -2
  149. package/assets/templates/helpers/check-architecture-sync.sh +1 -9
  150. package/assets/templates/helpers/check-task-sync.sh +82 -11
  151. package/assets/templates/helpers/check-task-workflow.sh +1 -3
  152. package/assets/templates/helpers/context-contract-sync.sh +1 -12
  153. package/assets/templates/helpers/contract-worktree.sh +26 -24
  154. package/assets/templates/helpers/ensure-task-workflow.sh +6 -8
  155. package/assets/templates/helpers/inspect-project-state.ts +1 -1
  156. package/assets/templates/helpers/migrate-project-template.sh +1 -1
  157. package/assets/templates/helpers/migrate-workflow-docs.ts +53 -239
  158. package/assets/templates/helpers/new-plan.sh +2 -2
  159. package/assets/templates/helpers/plan-to-todo.sh +3 -31
  160. package/assets/templates/helpers/sprint-backlog.sh +1 -1
  161. package/assets/templates/helpers/switch-plan.sh +1 -1
  162. package/assets/templates/helpers/workflow-contract.ts +1 -0
  163. package/assets/workflow-contract.v1.json +63 -171
  164. package/assets/workflows/xiaohongshu/xiaohongshu.collect-metrics.v1.draft.json +118 -0
  165. package/assets/workflows/xiaohongshu/xiaohongshu.publish-image-note.v1.draft.json +316 -0
  166. package/assets/workflows/xiaohongshu/xiaohongshu.publish-long-text.v1.draft.json +324 -0
  167. package/docs/architecture/CURRENT.md +233 -28
  168. package/docs/architecture/EVOLUTION.md +13 -0
  169. package/docs/architecture/decisions/20260801-controller-home-sqlite-state.md +2 -1
  170. package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +14 -5
  171. package/docs/architecture/decisions/20260823-immediate-controller-relay.md +6 -3
  172. package/docs/architecture/decisions/20260831-independent-windows-wsl-host-rescue.md +59 -0
  173. package/docs/architecture/decisions/20260904-ios-device-migration-baseline.md +120 -0
  174. package/docs/architecture/decisions/20260904-repository-runtime-data-boundary.md +42 -0
  175. package/docs/architecture/decisions/20260907-assistant-learning-loop.md +37 -0
  176. package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +311 -0
  177. package/docs/architecture/decisions/20260907-maintenance-diagnosis-bounded-read.md +39 -0
  178. package/docs/architecture/decisions/20260916-workflow-supervisor-authority.md +249 -0
  179. package/docs/architecture/decisions/20260917-cognitive-memory-foundation.md +82 -0
  180. package/docs/architecture/decisions/20260918-stable-candidate-release-lifecycle.md +221 -0
  181. package/docs/architecture/decisions/20260919-autonomous-work-liveness.md +62 -0
  182. package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +72 -0
  183. package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +237 -0
  184. package/docs/architecture/decisions/20261005-forge-v3-desktop-client-boundary.md +77 -0
  185. package/docs/architecture/domains/verification.md +8 -0
  186. package/docs/architecture/domains/workflow-engine.md +7 -1
  187. package/docs/architecture/index.md +3 -3
  188. package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +19 -8
  189. package/docs/architecture/requests/2026-09-04-computer-plugin-workflow-taxonomy.md +124 -0
  190. package/docs/forge-chatgpt-mcp-setup.md +5 -3
  191. package/docs/forge-plugin-management.md +20 -4
  192. package/docs/forge-runtime-self-healing-loop.md +2 -0
  193. package/docs/operations/benchmark-cross-version-freeze.md +38 -0
  194. package/docs/operations/controller-browser-plugin.md +3 -1
  195. package/docs/operations/controller-performance-and-502.md +17 -0
  196. package/docs/operations/controller-reliability-runbook.md +2 -2
  197. package/docs/operations/features.md +1 -1
  198. package/docs/operations/features.zh-CN.md +1 -1
  199. package/docs/operations/homebrew.md +2 -2
  200. package/docs/operations/mcp-tool-exposure.md +2 -0
  201. package/docs/operations/platform-support.md +16 -8
  202. package/docs/operations/platform-support.zh-CN.md +2 -2
  203. package/docs/operations/releasing.md +2 -0
  204. package/docs/operations/standalone-disaster-recovery.md +38 -5
  205. package/docs/operations/uu-remote-rescue.md +41 -0
  206. package/docs/operations/windows-wsl-host-rescue.md +133 -0
  207. package/docs/public-usage-guide.md +1 -1
  208. package/docs/public-usage-guide.zh-CN.md +1 -1
  209. package/docs/tutorials/01-install-and-start.md +1 -1
  210. package/docs/tutorials/01-install-and-start.zh-CN.md +1 -1
  211. package/docs/tutorials/02-connect-chatgpt.md +4 -4
  212. package/docs/tutorials/02-connect-chatgpt.zh-CN.md +4 -4
  213. package/docs/wiki/Implementation.md +1 -1
  214. package/package.json +46 -26
  215. package/packages/kernel/cognition/api/index.ts +6 -0
  216. package/packages/kernel/cognition/application/activation-service.ts +451 -0
  217. package/packages/kernel/cognition/application/consolidation-service.ts +185 -0
  218. package/packages/kernel/cognition/application/legacy-experience-adapter.ts +38 -0
  219. package/packages/kernel/cognition/application/memory-service.ts +64 -0
  220. package/packages/kernel/cognition/domain/learning.ts +106 -0
  221. package/packages/kernel/cognition/domain/memory.ts +254 -0
  222. package/packages/kernel/controller/api/index.ts +3 -0
  223. package/packages/kernel/controller/application/continuation-service.ts +281 -0
  224. package/packages/kernel/controller/application/controller-round-service.ts +41 -0
  225. package/packages/kernel/controller/application/controller-service.ts +30 -0
  226. package/packages/kernel/controller/domain/controller-round-transition-policy.ts +529 -0
  227. package/packages/kernel/controller/domain/controller-round.ts +110 -0
  228. package/packages/kernel/controller/domain/execution-quality.ts +135 -0
  229. package/packages/kernel/controller/domain/types.ts +56 -0
  230. package/packages/kernel/controller/index.ts +1 -0
  231. package/packages/kernel/controller/infrastructure/controller-binding-store.ts +84 -0
  232. package/packages/kernel/controller/infrastructure/controller-round-store.ts +1970 -0
  233. package/packages/kernel/controller/infrastructure/controller-session-store.ts +804 -0
  234. package/packages/kernel/controller/ports/controller-host.ts +18 -0
  235. package/packages/kernel/goal/api/index.ts +1 -0
  236. package/packages/kernel/goal/domain/types.ts +40 -0
  237. package/packages/kernel/goal/index.ts +1 -0
  238. package/packages/kernel/identity/api/index.ts +15 -0
  239. package/packages/kernel/identity/application/identity-service.ts +67 -0
  240. package/packages/kernel/identity/domain/activity-projection.ts +43 -0
  241. package/packages/kernel/identity/domain/capability-broker.ts +60 -0
  242. package/packages/kernel/identity/domain/grant.ts +72 -0
  243. package/packages/kernel/identity/domain/owned-resource.ts +116 -0
  244. package/packages/kernel/identity/domain/scope.ts +63 -0
  245. package/packages/kernel/identity/domain/semantic-sync.ts +81 -0
  246. package/packages/kernel/identity/domain/types.ts +44 -0
  247. package/packages/kernel/identity/domain/user-request.ts +93 -0
  248. package/packages/kernel/identity/domain/workspace.ts +56 -0
  249. package/packages/kernel/identity/index.ts +1 -0
  250. package/packages/kernel/identity/infrastructure/activity-projection-store.ts +77 -0
  251. package/packages/kernel/identity/infrastructure/capability-broker.ts +81 -0
  252. package/packages/kernel/identity/infrastructure/grant-store.ts +284 -0
  253. package/packages/kernel/identity/infrastructure/identity-store.ts +75 -0
  254. package/packages/kernel/identity/infrastructure/owned-resource-store.ts +259 -0
  255. package/packages/kernel/identity/infrastructure/user-request-store.ts +182 -0
  256. package/packages/kernel/memory/api/index.ts +5 -0
  257. package/packages/kernel/memory/application/experience-service.ts +118 -0
  258. package/packages/kernel/memory/application/outcome-service.ts +77 -0
  259. package/packages/kernel/memory/domain/experience.ts +103 -0
  260. package/packages/kernel/memory/domain/operational-prior.ts +92 -0
  261. package/packages/kernel/memory/index.ts +1 -0
  262. package/packages/kernel/scheduler/api/index.ts +4 -0
  263. package/packages/kernel/scheduler/application/eligibility.ts +252 -0
  264. package/packages/kernel/scheduler/application/schedule-service.ts +27 -0
  265. package/packages/kernel/scheduler/application/settlement.ts +182 -0
  266. package/packages/kernel/scheduler/domain/schedule.ts +236 -0
  267. package/packages/kernel/scheduler/index.ts +1 -0
  268. package/packages/kernel/scheduler/infrastructure/schedule-store.ts +805 -0
  269. package/packages/kernel/work/api/index.ts +16 -0
  270. package/packages/kernel/work/application/work-service.ts +123 -0
  271. package/packages/kernel/work/domain/check-receipt.ts +43 -0
  272. package/packages/kernel/work/domain/context-closure-receipt.ts +32 -0
  273. package/packages/kernel/work/domain/current-task-lineage.ts +104 -0
  274. package/packages/kernel/work/domain/engineering-contracts.ts +157 -0
  275. package/packages/kernel/work/domain/engineering-design.ts +286 -0
  276. package/packages/kernel/work/domain/engineering-profile.ts +238 -0
  277. package/packages/kernel/work/domain/evaluation-promotion-receipt.ts +186 -0
  278. package/packages/kernel/work/domain/execution-concurrency.ts +247 -0
  279. package/packages/kernel/work/domain/execution-snapshot.ts +2 -0
  280. package/packages/kernel/work/domain/implementation-review.ts +193 -0
  281. package/packages/kernel/work/domain/objective-graph.ts +119 -0
  282. package/packages/kernel/work/domain/project-engineering-contract.ts +224 -0
  283. package/packages/kernel/work/domain/repository-completion-receipt.ts +73 -0
  284. package/{src/runtime/control-plane/facade/work-state-machine.ts → packages/kernel/work/domain/state-machine.ts} +37 -66
  285. package/packages/kernel/work/domain/types.ts +534 -0
  286. package/packages/kernel/work/index.ts +1 -0
  287. package/packages/kernel/work/infrastructure/work-contract-store.ts +1967 -0
  288. package/packages/kernel/work/ports/work-contract-store.ts +21 -0
  289. package/packages/plugin-runtime/browser/index.ts +3 -0
  290. package/packages/plugin-runtime/browser/provider-registry.ts +110 -0
  291. package/packages/plugin-runtime/browser/runtime-contract.ts +150 -0
  292. package/packages/plugin-runtime/browser/session-authority.ts +62 -0
  293. package/packages/plugin-runtime/computer/chatgpt-identity.ts +24 -0
  294. package/packages/plugin-runtime/computer/conversation-target.ts +143 -0
  295. package/packages/plugin-runtime/computer/index.ts +8 -0
  296. package/packages/plugin-runtime/computer/provider-error.ts +26 -0
  297. package/packages/plugin-runtime/computer/provider-registration.ts +52 -0
  298. package/packages/plugin-runtime/computer/provider-registry.ts +63 -0
  299. package/packages/plugin-runtime/computer/provider.ts +19 -0
  300. package/packages/plugin-runtime/computer/target-authority.ts +215 -0
  301. package/packages/plugin-runtime/computer/target-persistence.ts +54 -0
  302. package/packages/plugin-runtime/external/index.ts +1 -0
  303. package/packages/plugin-runtime/external/unix-jsonl-transport.ts +581 -0
  304. package/packages/plugin-runtime/index.ts +3 -0
  305. package/packages/protocols/browser/index.ts +1 -0
  306. package/packages/protocols/browser/session.ts +98 -0
  307. package/packages/protocols/computer/contract.ts +225 -0
  308. package/packages/protocols/computer/index.ts +1 -0
  309. package/packages/protocols/failure/contract.ts +158 -0
  310. package/packages/protocols/failure/index.ts +1 -0
  311. package/packages/protocols/handoff/index.ts +1 -0
  312. package/packages/protocols/handoff/status.ts +22 -0
  313. package/packages/protocols/mcp/execution-context.ts +11 -0
  314. package/packages/protocols/mcp/index.ts +2 -0
  315. package/packages/protocols/mcp/tool-contract.ts +42 -0
  316. package/packages/workflow-runtime/api/index.ts +2 -0
  317. package/packages/workflow-runtime/application/interpreter.ts +342 -0
  318. package/packages/workflow-runtime/domain/workflow-asset.ts +223 -0
  319. package/packages/workflow-runtime/index.ts +1 -0
  320. package/scripts/activate-source-baseline.ts +7 -9
  321. package/scripts/assemble-template.ts +1 -1
  322. package/scripts/bootstrap-runtime-maintenance-recovery.sh +4 -1
  323. package/scripts/canary-chatgpt-provider-delivery.ts +97 -0
  324. package/scripts/canary-controller-semantic-wait.ts +183 -0
  325. package/scripts/canary-global-hook.sh +2 -2
  326. package/scripts/check-mcp-compatibility.ts +85 -7
  327. package/scripts/check-platform-support.mjs +28 -2
  328. package/scripts/check-public-docs.sh +1 -1
  329. package/scripts/check-repository-hygiene.mjs +92 -0
  330. package/scripts/check-runtime-architecture.mjs +1643 -127
  331. package/scripts/check-source-duplication.mjs +9 -1
  332. package/scripts/controller-ngrok-rotation.sh +5 -4
  333. package/scripts/create-project-dirs.sh +10 -74
  334. package/scripts/forge-local-recovery-helper.mjs +282 -0
  335. package/scripts/forge-uu-remote-rescue-helper.d.mts +31 -0
  336. package/scripts/forge-uu-remote-rescue-helper.mjs +409 -0
  337. package/scripts/forge-windows-host-recovery-helper.mjs +136 -0
  338. package/scripts/hook-shim.sh +2 -2
  339. package/scripts/init-project.sh +12 -70
  340. package/scripts/install-desktop-operator-registration.ts +4 -2
  341. package/scripts/install-independent-windows-wsl-recovery.ts +125 -0
  342. package/scripts/install-standalone-recovery.ts +122 -10
  343. package/scripts/install-uu-remote-rescue-registration.ts +74 -0
  344. package/scripts/install-windows-host-recovery-registration.ts +22 -0
  345. package/scripts/lib/controller-home-env.sh +6 -3
  346. package/scripts/lib/project-init-lib.sh +42 -582
  347. package/scripts/migrate-chatgpt-automation-schedules.ts +2 -2
  348. package/scripts/migrate-windows-wsl-controller-home.ts +306 -0
  349. package/scripts/open-source-audit-allowlist.txt +11 -1
  350. package/scripts/portability-bindings.mjs +70 -0
  351. package/scripts/run-bounded-command.mjs +60 -0
  352. package/scripts/run-bun-test-file.ts +22 -6
  353. package/scripts/run-governed-gate.ts +4 -2
  354. package/scripts/run-mobile-monitor-bridge.ts +0 -1
  355. package/scripts/smoke-control-plane-failure-domain.ts +94 -0
  356. package/scripts/smoke-mcp-http-runtime.ts +6 -1
  357. package/scripts/smoke-runtime-recovery.ts +13 -11
  358. package/scripts/smoke-schedule-engine.ts +24 -16
  359. package/scripts/smoke-unattended-transport-recovery.ts +223 -0
  360. package/scripts/smoke-user-request-continuation-restart.ts +232 -0
  361. package/scripts/smoke-workflow-supervisor-chrome-adapter.ts +92 -0
  362. package/scripts/smoke-workflow-supervisor-process-restart.ts +276 -0
  363. package/scripts/smoke-workflow-supervisor-restart-recovery.ts +150 -0
  364. package/scripts/smoke-workflow-supervisor.ts +103 -0
  365. package/scripts/test-governance.ts +51 -2
  366. package/scripts/verify-forge-runtime.sh +2 -1
  367. package/src/cli/agent-jobs/executor-health.ts +11 -34
  368. package/src/cli/agent-jobs/integration.ts +18 -49
  369. package/src/cli/agent-jobs/job-manager.ts +17 -4
  370. package/src/cli/chatgpt-browser/bind-server.ts +2 -1
  371. package/src/cli/chatgpt-browser/binding.ts +20 -10
  372. package/src/cli/chatgpt-browser/bridge-extension.ts +75 -0
  373. package/src/cli/chatgpt-browser/bridge-provider.ts +376 -11
  374. package/src/cli/chatgpt-browser/engine.ts +10 -11
  375. package/src/cli/chatgpt-browser/native-provider.ts +24 -83
  376. package/src/cli/chatgpt-browser/oracle-provider.ts +5 -3
  377. package/src/cli/chatgpt-browser/types.ts +1 -0
  378. package/src/cli/commands/bootstrap-control.ts +334 -0
  379. package/src/cli/commands/brain-assistant.ts +52 -0
  380. package/src/cli/commands/brain.ts +191 -40
  381. package/src/cli/commands/chatgpt.ts +32 -67
  382. package/src/cli/commands/computer.ts +437 -0
  383. package/src/cli/commands/doctor.ts +18 -1
  384. package/src/cli/commands/init-hook.ts +71 -61
  385. package/src/cli/commands/init.ts +3 -1
  386. package/src/cli/commands/mcp.ts +16 -10
  387. package/src/cli/commands/plugin.ts +38 -12
  388. package/src/cli/commands/recovery.ts +507 -80
  389. package/src/cli/commands/runtime.ts +12 -7
  390. package/src/cli/commands/setup-profile.ts +97 -39
  391. package/src/cli/commands/status.ts +2 -1
  392. package/src/cli/controller/check-runner.ts +500 -100
  393. package/src/cli/controller/completion-backlog.ts +3 -3
  394. package/src/cli/controller/completion-orchestrator.ts +4 -43
  395. package/src/cli/controller/completion-target.ts +3 -72
  396. package/src/cli/controller/context/source-materializer.ts +81 -100
  397. package/src/cli/controller/context/types.ts +7 -1
  398. package/src/cli/controller/context-pack.ts +28 -6
  399. package/src/cli/controller/execution-completion.ts +4 -7
  400. package/src/cli/controller/execution-policy.ts +36 -153
  401. package/src/cli/controller/governance.ts +2 -3
  402. package/src/cli/controller/issue-store.ts +4 -99
  403. package/src/cli/controller/launch-agents.ts +59 -18
  404. package/src/cli/controller/operational-plan.ts +24 -51
  405. package/src/cli/controller/runtime-config.ts +5 -1
  406. package/src/cli/controller/stuck-state-migration.ts +2 -3
  407. package/src/cli/controller/systemd-user.ts +148 -0
  408. package/src/cli/controller/types.ts +10 -70
  409. package/src/cli/controller/worklog.ts +67 -13
  410. package/src/cli/editing/edit-operation-contract.ts +92 -0
  411. package/src/cli/editing/edit-session.ts +290 -20
  412. package/src/cli/github/plugin.ts +17 -12
  413. package/src/cli/hook/route-registry.ts +3 -5
  414. package/src/cli/hook/runtime.ts +49 -3
  415. package/src/cli/index.ts +3 -0
  416. package/src/cli/local-bridge/connector-freshness.ts +2 -2
  417. package/src/cli/local-bridge/console-automations.ts +20 -15
  418. package/src/cli/local-bridge/console-view-models.ts +3 -12
  419. package/src/cli/local-bridge/facade-api.ts +105 -205
  420. package/src/cli/local-bridge/job-store.ts +1 -1
  421. package/src/cli/local-bridge/server.ts +48 -174
  422. package/src/cli/local-bridge/types.ts +0 -1
  423. package/src/cli/mcp/access-mode.ts +2 -132
  424. package/src/cli/mcp/access-tools.ts +2 -387
  425. package/src/cli/mcp/audit.ts +2 -32
  426. package/src/cli/mcp/auth.ts +2 -404
  427. package/src/cli/mcp/instructions.ts +2 -34
  428. package/src/cli/mcp/legacy-context.ts +2 -16
  429. package/src/cli/mcp/legacy-tool-service.ts +2 -5308
  430. package/src/cli/mcp/multi-repository.ts +2 -436
  431. package/src/cli/mcp/oauth-client-retirement.ts +74 -0
  432. package/src/cli/mcp/oauth.ts +2 -375
  433. package/src/cli/mcp/openai-secure-tunnel.ts +2 -0
  434. package/src/cli/mcp/paths.ts +2 -140
  435. package/src/cli/mcp/policy.ts +2 -232
  436. package/src/cli/mcp/post-finalize-work-attribution.ts +2 -150
  437. package/src/cli/mcp/proxy-env.ts +2 -62
  438. package/src/cli/mcp/readiness-projection.ts +2 -24
  439. package/src/cli/mcp/redaction.ts +2 -21
  440. package/src/cli/mcp/repo.ts +2 -24
  441. package/src/cli/mcp/repository-tools.ts +2 -1613
  442. package/src/cli/mcp/server.ts +2 -951
  443. package/src/cli/mcp/setup.ts +2 -737
  444. package/src/cli/mcp/tool-capability-cache.ts +2 -87
  445. package/src/cli/mcp/tool-contract.ts +2 -14
  446. package/src/cli/mcp/tools.ts +2 -9
  447. package/src/cli/mcp/toolset-names.ts +2 -70
  448. package/src/cli/mcp/toolset-selection.ts +2 -41
  449. package/src/cli/mcp/toolset.ts +2 -336
  450. package/src/cli/mcp/transports/AGENTS.md +1 -10
  451. package/src/cli/mcp/transports/CLAUDE.md +1 -10
  452. package/src/cli/mcp/transports/http.ts +2 -1414
  453. package/src/cli/mcp/transports/session-registry.ts +2 -490
  454. package/src/cli/mcp/transports/stdio.ts +2 -8
  455. package/src/cli/mcp/types.ts +2 -41
  456. package/src/cli/mcp/umbrella-tools.ts +2 -117
  457. package/src/cli/repositories/command-executor.ts +91 -39
  458. package/src/cli/repositories/command-scope.ts +139 -4
  459. package/src/cli/repositories/controller-home.ts +167 -1
  460. package/src/cli/repositories/ephemeral-workspace.ts +20 -30
  461. package/src/cli/repositories/git-command-executor.ts +2 -2
  462. package/src/cli/repositories/identity.ts +13 -0
  463. package/src/cli/repositories/registry.ts +145 -60
  464. package/src/cli/repositories/repository-snapshot.ts +53 -7
  465. package/src/cli/repositories/runtime-storage.ts +27 -2
  466. package/src/cli/repositories/safe-patch.ts +34 -38
  467. package/src/cli/repositories/selected-path-actions.ts +22 -2
  468. package/src/cli/repositories/structured-git.ts +167 -27
  469. package/src/cli/repository/session-cache.ts +92 -6
  470. package/src/cli/runtime/helper-runner.ts +7 -0
  471. package/src/cli/runtime-invocation.ts +8 -1
  472. package/src/cli/tools/codegraph.ts +44 -25
  473. package/src/core/adoption/manifest-templates.ts +1 -1
  474. package/src/core/adoption/plan.ts +3 -26
  475. package/src/core/adoption/workflow-contract-plan.ts +17 -9
  476. package/src/effects/process-runner.ts +8 -14
  477. package/src/runtime/context/assistant-context.ts +167 -0
  478. package/src/runtime/context/assistant-work-context.ts +209 -0
  479. package/src/runtime/context/automatic-learning.ts +565 -0
  480. package/src/runtime/context/codegraph-cache-boundary.ts +255 -0
  481. package/src/runtime/context/codegraph-read-provider.ts +55 -22
  482. package/src/runtime/context/codegraph-sidecar.cjs +8 -1
  483. package/src/runtime/context/cognitive-attention.ts +173 -0
  484. package/src/runtime/context/cognitive-skill-canary.ts +158 -0
  485. package/src/runtime/context/context-closure.ts +305 -0
  486. package/src/runtime/context/context-pack-process.ts +103 -0
  487. package/src/runtime/context/context-plane.ts +203 -0
  488. package/src/runtime/context/direct-controller-learning.ts +298 -0
  489. package/src/runtime/context/project-engineering-contract.ts +60 -0
  490. package/src/runtime/context/semantic-navigation-contract.ts +9 -0
  491. package/src/runtime/context/semantic-navigation.ts +6 -34
  492. package/src/runtime/context/typescript-navigation-process.ts +145 -0
  493. package/src/runtime/context/typescript-navigation.ts +89 -3
  494. package/src/runtime/control-plane/bootstrap/capability-provider.ts +74 -0
  495. package/src/runtime/control-plane/bootstrap/control-api.ts +57 -0
  496. package/src/runtime/control-plane/bootstrap/index.ts +5 -0
  497. package/src/runtime/control-plane/bootstrap/state-machine.ts +141 -0
  498. package/src/runtime/control-plane/bootstrap/store.ts +21 -0
  499. package/src/runtime/control-plane/bootstrap/types.ts +87 -0
  500. package/src/runtime/control-plane/cleanup-artifact-retention.ts +531 -0
  501. package/src/runtime/control-plane/codegraph-cache-retention.ts +164 -0
  502. package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +282 -0
  503. package/src/runtime/control-plane/execution/controller-authority-recovery.ts +380 -0
  504. package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +113 -16
  505. package/src/runtime/control-plane/execution/execution-identity.ts +23 -3
  506. package/src/runtime/control-plane/execution/implementation-review-content.ts +95 -0
  507. package/src/runtime/control-plane/execution/repository-work-attribution.ts +7 -30
  508. package/src/runtime/control-plane/execution/retained-work-resume.ts +439 -102
  509. package/src/runtime/control-plane/execution/session-store.ts +31 -1
  510. package/src/runtime/control-plane/execution/validation.ts +34 -11
  511. package/src/runtime/control-plane/execution/work-authority-reconciler.ts +87 -0
  512. package/src/runtime/control-plane/execution/work-check-evidence.ts +137 -0
  513. package/src/runtime/control-plane/execution/work-completion-authority.ts +31 -44
  514. package/src/runtime/control-plane/execution/work-delivery-service.ts +497 -0
  515. package/src/runtime/control-plane/execution/work-evidence-policy.ts +46 -53
  516. package/src/runtime/control-plane/execution/work-execution-support.ts +85 -164
  517. package/src/runtime/control-plane/execution/work-handle-authority.ts +349 -73
  518. package/src/runtime/control-plane/execution/work-handle-store.ts +55 -2
  519. package/src/runtime/control-plane/execution/work-head-settlement.ts +108 -0
  520. package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +173 -28
  521. package/src/runtime/control-plane/execution/work-operation-service.ts +92 -40
  522. package/src/runtime/control-plane/execution/work-preparation-service.ts +145 -269
  523. package/src/runtime/control-plane/execution/work-remote-delivery.ts +2 -3
  524. package/src/runtime/control-plane/execution/work-revision-diff.ts +39 -0
  525. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +543 -225
  526. package/src/runtime/control-plane/execution/work-validation-reconciler.ts +59 -45
  527. package/src/runtime/control-plane/execution/work-verification-context.ts +1 -1
  528. package/src/runtime/control-plane/execution/work-verification-service.ts +662 -52
  529. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +205 -16
  530. package/src/runtime/control-plane/facade/capability-registry.ts +380 -44
  531. package/src/runtime/control-plane/facade/check-normalization.ts +3 -9
  532. package/src/runtime/control-plane/facade/codex-delegation.ts +10 -11
  533. package/src/runtime/control-plane/facade/controller-connection.ts +135 -0
  534. package/src/runtime/control-plane/facade/controller-session-store.ts +2 -488
  535. package/src/runtime/control-plane/facade/goal-workloop-access.ts +6 -22
  536. package/src/runtime/control-plane/facade/goal-workloop.ts +565 -1202
  537. package/src/runtime/control-plane/facade/handoff-inbox-application.ts +145 -0
  538. package/src/runtime/control-plane/facade/handoff-inbox-store.ts +266 -52
  539. package/src/runtime/control-plane/facade/index.ts +4 -3
  540. package/src/runtime/control-plane/facade/operation-digest.ts +34 -73
  541. package/src/runtime/control-plane/facade/plan-contract-store.ts +671 -245
  542. package/src/runtime/control-plane/facade/policy-gate.ts +0 -23
  543. package/src/runtime/control-plane/facade/repository-work-admission.ts +31 -23
  544. package/src/runtime/control-plane/facade/requirement-authority.ts +121 -0
  545. package/src/runtime/control-plane/facade/requirement-board.ts +9 -4
  546. package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +85 -0
  547. package/src/runtime/control-plane/facade/self-healing-loop.ts +18 -53
  548. package/src/runtime/control-plane/facade/semantic-admission.ts +8 -16
  549. package/src/runtime/control-plane/facade/suggested-actions.ts +15 -15
  550. package/src/runtime/control-plane/facade/types.ts +218 -620
  551. package/src/runtime/control-plane/facade/work-continuation.ts +8 -8
  552. package/src/runtime/control-plane/facade/work-contract-store.ts +2 -1043
  553. package/src/runtime/control-plane/generated-cache-retention.ts +336 -19
  554. package/src/runtime/control-plane/global-scheduler/autonomous-continuation.ts +248 -0
  555. package/src/runtime/control-plane/global-scheduler/durable-admission.ts +13 -2
  556. package/src/runtime/control-plane/global-scheduler/maintenance.ts +274 -84
  557. package/src/runtime/control-plane/global-scheduler/periodic-cleanup-entry.ts +55 -0
  558. package/src/runtime/control-plane/global-scheduler/periodic-cleanup-process.ts +98 -0
  559. package/src/runtime/control-plane/global-scheduler/reconciliation.ts +3 -2
  560. package/src/runtime/control-plane/global-scheduler/scheduler-worker-entry.ts +10 -0
  561. package/src/runtime/control-plane/global-scheduler/scheduler.ts +227 -109
  562. package/src/runtime/control-plane/global-scheduler/wake-signal.ts +42 -2
  563. package/src/runtime/control-plane/global-scheduler/worker-launch.ts +18 -6
  564. package/src/runtime/control-plane/governance/access-policy.ts +19 -2
  565. package/src/runtime/control-plane/governance/authorization.ts +20 -3
  566. package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +160 -0
  567. package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +2 -177
  568. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +139 -670
  569. package/src/runtime/control-plane/launcher/local-conversation-controller.ts +238 -0
  570. package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +25 -6
  571. package/src/runtime/control-plane/launcher/thin-launcher.ts +96 -194
  572. package/src/runtime/control-plane/lifecycle-retention-metrics.ts +60 -0
  573. package/src/runtime/control-plane/persistence/cognition-store.ts +820 -0
  574. package/src/runtime/control-plane/persistence/experience-store.ts +302 -0
  575. package/src/runtime/control-plane/persistence/operational-prior-store.ts +348 -0
  576. package/src/runtime/control-plane/persistence/requirement-store.ts +230 -80
  577. package/src/runtime/control-plane/persistence/sqlite-store.ts +654 -78
  578. package/src/runtime/control-plane/persistence/workflow-content-store.ts +98 -0
  579. package/src/runtime/control-plane/persistence/workflow-registry-store.ts +186 -0
  580. package/src/runtime/control-plane/persistence/workflow-run-store.ts +123 -0
  581. package/src/runtime/control-plane/release-retention.ts +154 -26
  582. package/src/runtime/control-plane/repository-namespace-retention.ts +208 -0
  583. package/src/runtime/control-plane/runtime-cleanup.ts +844 -38
  584. package/src/runtime/control-plane/runtime-generation.ts +6 -0
  585. package/src/runtime/control-plane/workspace/project-onboarding.ts +80 -0
  586. package/src/runtime/control-plane/workspace/semantic-sync-service.ts +479 -0
  587. package/src/runtime/control-plane/workspace/workspace-store.ts +249 -0
  588. package/src/runtime/diagnostics/incident-repair.ts +573 -0
  589. package/src/runtime/diagnostics/mcp-timing.ts +239 -6
  590. package/src/runtime/diagnostics/performance.ts +6 -14
  591. package/src/runtime/diagnostics/read-only-tool.ts +1 -1
  592. package/src/runtime/evidence/artifact-store.ts +216 -35
  593. package/src/runtime/evidence/evidence-store.ts +112 -8
  594. package/src/runtime/evidence/operational-shadow.ts +38 -0
  595. package/src/runtime/evidence/output-handle-index.ts +225 -0
  596. package/src/runtime/evidence/process-check-receipt.ts +5 -43
  597. package/src/runtime/evidence/result-store.ts +158 -44
  598. package/src/runtime/evidence/sensitive-output.ts +4 -4
  599. package/src/runtime/execution/jobs/receipt-recovery.ts +1 -1
  600. package/src/runtime/execution/jobs/store.ts +124 -6
  601. package/src/runtime/execution/managed-workspace.ts +112 -5
  602. package/src/runtime/execution/process-runtime/canary.ts +19 -5
  603. package/src/runtime/execution/process-runtime/check-classification.ts +48 -0
  604. package/src/runtime/execution/process-runtime/check-facade.ts +24 -10
  605. package/src/runtime/execution/process-runtime/check-receipt.ts +1 -1
  606. package/src/runtime/execution/process-runtime/check-result-retention.ts +132 -0
  607. package/src/runtime/execution/process-runtime/check-result.ts +177 -2
  608. package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +58 -9
  609. package/src/runtime/execution/process-runtime/check-storage.ts +187 -0
  610. package/src/runtime/execution/process-runtime/command-facade.ts +117 -114
  611. package/src/runtime/execution/process-runtime/gc.ts +15 -2
  612. package/src/runtime/execution/process-runtime/handle-index.ts +176 -0
  613. package/src/runtime/execution/process-runtime/host-command-lane.ts +139 -0
  614. package/src/runtime/execution/process-runtime/index.ts +4 -0
  615. package/src/runtime/execution/process-runtime/interactive-admission.ts +2 -1
  616. package/src/runtime/execution/process-runtime/lightweight-managed.ts +283 -73
  617. package/src/runtime/execution/process-runtime/persisted-check.ts +130 -23
  618. package/src/runtime/execution/process-runtime/process-runner-entry.ts +47 -5
  619. package/src/runtime/execution/process-runtime/process-scope.ts +160 -0
  620. package/src/runtime/execution/process-runtime/resource-claims.ts +125 -64
  621. package/src/runtime/execution/process-runtime/runtime.ts +167 -17
  622. package/src/runtime/execution/process-runtime/store.ts +30 -2
  623. package/src/runtime/execution/process-runtime/types.ts +27 -0
  624. package/src/runtime/execution/workers/executor.ts +18 -19
  625. package/src/runtime/execution/workers/worker-entry.ts +1 -1
  626. package/src/runtime/gateway/mcp/execution-tools.ts +2 -207
  627. package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +2 -61
  628. package/src/runtime/gateway/mcp/persisted-check-process.ts +2 -3
  629. package/src/runtime/gateway/mcp/process-tools.ts +2 -289
  630. package/src/runtime/gateway/mcp/router.ts +2 -1125
  631. package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +2 -565
  632. package/src/runtime/gateway/mcp/runtime-tools.ts +2 -6655
  633. package/src/runtime/gateway/mcp/work-validation-reconciler.ts +2 -1
  634. package/src/runtime/maintenance/cleanup.ts +38 -24
  635. package/src/runtime/platform/browser-product-discovery.ts +174 -0
  636. package/src/runtime/platform/computer-platform.ts +14 -0
  637. package/src/runtime/platform/executable-discovery.ts +54 -0
  638. package/src/runtime/platform/fetch-http-server.ts +90 -0
  639. package/src/runtime/platform/service-inventory.ts +130 -0
  640. package/src/runtime/platform/service-manager.ts +146 -0
  641. package/src/runtime/platform/windows-host-discovery.ts +118 -0
  642. package/src/runtime/platform/windows-recovery-deployment.ts +67 -0
  643. package/src/runtime/plugins/action-application.ts +192 -0
  644. package/src/runtime/plugins/app-store-connect-adapter.ts +47 -35
  645. package/src/runtime/plugins/browser-adapter.ts +898 -135
  646. package/src/runtime/plugins/browser-automation-service.ts +33 -34
  647. package/src/runtime/plugins/browser-macos-bridge.ts +386 -46
  648. package/src/runtime/plugins/browser-manifest-surface.ts +75 -17
  649. package/src/runtime/plugins/browser-native-session-service.ts +64 -14
  650. package/src/runtime/plugins/browser-provider-registry.ts +2 -109
  651. package/src/runtime/plugins/browser-registration.ts +32 -0
  652. package/src/runtime/plugins/browser-runtime-contract.ts +2 -154
  653. package/src/runtime/plugins/browser-runtime.ts +55 -10
  654. package/src/runtime/plugins/browser-session-authority.ts +101 -291
  655. package/src/runtime/plugins/browser-session-legacy-migration.ts +203 -0
  656. package/src/runtime/plugins/browser-session-store.ts +243 -80
  657. package/src/runtime/plugins/browser-session-types.ts +2 -98
  658. package/src/runtime/plugins/capability-authorization-grants.ts +272 -59
  659. package/src/runtime/plugins/catalog-trust.ts +82 -0
  660. package/src/runtime/plugins/computer-chatgpt-browser-adapter-installer.ts +219 -0
  661. package/src/runtime/plugins/computer-chatgpt-macos-target.ts +891 -0
  662. package/src/runtime/plugins/computer-registration.ts +1050 -0
  663. package/src/runtime/plugins/config-store.ts +119 -0
  664. package/src/runtime/plugins/desktop-operator-external-policy.ts +964 -0
  665. package/src/runtime/plugins/desktop-operator-registration.ts +123 -12
  666. package/src/runtime/plugins/errors.ts +8 -1
  667. package/src/runtime/plugins/external-adapter.ts +82 -323
  668. package/src/runtime/plugins/external-provider-policy.ts +48 -0
  669. package/src/runtime/plugins/external-registration.ts +30 -2
  670. package/src/runtime/plugins/external-unix-socket-probe.cjs +9 -3
  671. package/src/runtime/plugins/external-unix-socket.ts +64 -193
  672. package/src/runtime/plugins/first-party-external-registration.ts +163 -0
  673. package/src/runtime/plugins/first-party-registry.ts +3 -1
  674. package/src/runtime/plugins/github-adapter.ts +1 -2
  675. package/src/runtime/plugins/gmail-adapter.ts +29 -8
  676. package/src/runtime/plugins/google-calendar-adapter.ts +8 -8
  677. package/src/runtime/plugins/google-shared.ts +45 -53
  678. package/src/runtime/plugins/google-tasks-adapter.ts +8 -8
  679. package/src/runtime/plugins/ios-adapter.ts +2 -3
  680. package/src/runtime/plugins/lightweight-action.ts +208 -2
  681. package/src/runtime/plugins/local-system-adapter.ts +192 -2
  682. package/src/runtime/plugins/macos-capability-broker.ts +15 -105
  683. package/src/runtime/plugins/managed-process-adapter.ts +12 -5
  684. package/src/runtime/plugins/plugin-action-sidecar.ts +17 -13
  685. package/src/runtime/plugins/plugin-management-adapter.ts +1 -1
  686. package/src/runtime/plugins/resend-adapter.ts +15 -24
  687. package/src/runtime/plugins/store.ts +1003 -387
  688. package/src/runtime/plugins/types.ts +28 -1
  689. package/src/runtime/plugins/uu-remote-rescue-registration.ts +155 -0
  690. package/src/runtime/plugins/windows-host-recovery-install.ts +68 -0
  691. package/src/runtime/plugins/windows-host-recovery-registration.ts +85 -0
  692. package/src/runtime/plugins/xiaohongshu-publish.ts +102 -430
  693. package/src/runtime/projections/controller-context.ts +12 -6
  694. package/src/runtime/projections/git-status-sampler.ts +73 -22
  695. package/src/runtime/projections/invalidation.ts +7 -3
  696. package/src/runtime/projections/materialized-view.ts +93 -43
  697. package/src/runtime/recovery/actions.ts +3 -3
  698. package/src/runtime/recovery/capability-action-application.ts +229 -0
  699. package/src/runtime/recovery/index.ts +3 -0
  700. package/src/runtime/recovery/lifecycle-inventory.ts +338 -0
  701. package/src/runtime/recovery/local-jobs-repair.ts +14 -14
  702. package/src/runtime/recovery/maintenance-executor.ts +701 -168
  703. package/src/runtime/recovery/quarantine-retention.ts +256 -0
  704. package/src/runtime/recovery/store.ts +29 -11
  705. package/src/runtime/release/identity.ts +6 -0
  706. package/src/runtime/release/release-coordinator.ts +296 -0
  707. package/src/runtime/release/release-session.ts +716 -0
  708. package/src/runtime/release/release-state-migration.ts +25 -0
  709. package/src/runtime/resources/leases/store.ts +56 -25
  710. package/src/runtime/root/active-execution-power-assertion.ts +139 -0
  711. package/src/runtime/root/assistant-learning-loop.ts +45 -0
  712. package/src/runtime/root/browser-session-composition.ts +59 -0
  713. package/src/runtime/root/computer-composition.ts +376 -0
  714. package/src/runtime/root/computer-target-composition.ts +16 -0
  715. package/src/runtime/root/computer-target-persistence.ts +39 -0
  716. package/src/runtime/root/controller-progression-composition.ts +192 -0
  717. package/src/runtime/root/controller-round-composition.ts +126 -0
  718. package/src/runtime/root/controller-services.ts +2 -0
  719. package/src/runtime/root/deployment-topology.ts +106 -0
  720. package/src/runtime/root/entry.ts +8 -6
  721. package/src/runtime/root/gateway-adapter.ts +3 -3
  722. package/src/runtime/root/known-good-recovery.ts +184 -0
  723. package/src/runtime/root/local-bridge.ts +5 -3
  724. package/src/runtime/root/mcp-transport.ts +116 -23
  725. package/src/runtime/root/ownership.ts +261 -9
  726. package/src/runtime/root/package-connector-service.ts +212 -74
  727. package/src/runtime/root/package-runtime-release.ts +199 -33
  728. package/src/runtime/root/package-runtime-service.ts +77 -108
  729. package/src/runtime/root/release-execution-canary.ts +103 -0
  730. package/src/runtime/root/release-loader.ts +150 -0
  731. package/src/runtime/root/release-manifest.ts +185 -7
  732. package/src/runtime/root/release-materialize.ts +474 -31
  733. package/src/runtime/root/release-store.ts +425 -37
  734. package/src/runtime/root/runtime-lane.ts +191 -0
  735. package/src/runtime/root/runtime.ts +379 -32
  736. package/src/runtime/root/scheduled-controller-composition.ts +76 -0
  737. package/src/runtime/root/scheduler.ts +12 -4
  738. package/src/runtime/root/service-runner.ts +3 -3
  739. package/src/runtime/root/service.ts +73 -45
  740. package/src/runtime/root/status.ts +49 -0
  741. package/src/runtime/root/types.ts +55 -3
  742. package/src/runtime/root/workflow-supervisor-composition.ts +493 -0
  743. package/src/runtime/root/workflow-supervisor-runtime.ts +209 -0
  744. package/src/runtime/root/write-fence.ts +50 -2
  745. package/src/runtime/safe-tooling/google-credential-store.ts +76 -21
  746. package/src/runtime/safe-tooling/google-oauth-broker.ts +25 -7
  747. package/src/runtime/safe-tooling/workspace-auth.ts +1 -1
  748. package/src/runtime/shared/bounded-child-supervisor.ts +9 -1
  749. package/src/runtime/shared/local-bridge-surface.ts +1 -1
  750. package/src/runtime/shared/process-environment.ts +36 -10
  751. package/src/runtime/shared/response-budget.ts +1 -3
  752. package/src/runtime/shared/storage-capacity.ts +68 -0
  753. package/src/runtime/standalone-recovery/controller-home-migration.ts +1108 -0
  754. package/src/runtime/standalone-recovery/core.ts +4609 -495
  755. package/src/runtime/standalone-recovery/entry.ts +642 -81
  756. package/src/runtime/standalone-recovery/independent-host-rescue.ts +172 -0
  757. package/src/runtime/standalone-recovery/installer.ts +399 -177
  758. package/src/runtime/standalone-recovery/mcp-server.ts +79 -0
  759. package/src/runtime/standalone-recovery/mutation-identity-contract.ts +21 -0
  760. package/src/runtime/standalone-recovery/operation-lock.ts +160 -0
  761. package/src/runtime/standalone-recovery/performance.ts +173 -0
  762. package/src/runtime/standalone-recovery/release.ts +58 -5
  763. package/src/runtime/standalone-recovery/service-labels.ts +5 -2
  764. package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +5 -2
  765. package/src/runtime/watchdog/workflow-watchdog.ts +1 -1
  766. package/src/runtime/workflow/schedules/browser-probe.ts +17 -6
  767. package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +11 -4
  768. package/src/runtime/workflow/schedules/engine.ts +298 -484
  769. package/src/runtime/workflow/schedules/pending-activation.ts +1 -1
  770. package/src/runtime/workflow/schedules/settlement.ts +2 -191
  771. package/src/runtime/workflow/schedules/store.ts +2 -607
  772. package/src/runtime/workflow/schedules/types.ts +2 -127
  773. package/src/runtime/workflow/schedules/work-continuation.ts +220 -16
  774. package/src/runtime/workflows/first-party/xiaohongshu.ts +122 -0
  775. package/src/runtime/workflows/runtime.ts +482 -0
  776. package/src/testing/test-governance.ts +95 -30
  777. package/supervisor/chatgpt-conversation.ts +23 -0
  778. package/supervisor/client.ts +201 -0
  779. package/supervisor/control-plane.ts +868 -0
  780. package/supervisor/entry.ts +15 -0
  781. package/supervisor/forge-validators.ts +80 -0
  782. package/supervisor/index.ts +5 -0
  783. package/supervisor/native-browser-adapter.ts +786 -0
  784. package/supervisor/native-messaging/host.ts +39 -0
  785. package/supervisor/native-messaging/manifest.ts +26 -0
  786. package/supervisor/native-messaging/protocol.ts +27 -0
  787. package/supervisor/paths.ts +18 -0
  788. package/supervisor/protocol.ts +202 -0
  789. package/supervisor/server.ts +404 -0
  790. package/supervisor/store.ts +1451 -0
  791. package/supervisor/tsconfig.json +8 -0
  792. package/supervisor/types.ts +255 -0
  793. package/assets/templates/helpers/archive-architecture-request.sh +0 -244
  794. package/docs/architecture/history/README.md +0 -7
  795. package/docs/architecture/history/chatgpt-handoff-facade.md +0 -397
  796. package/docs/architecture/history/global-hook-runtime.md +0 -166
  797. package/docs/architecture/history/ios-semantic-automation-provider-v2.md +0 -170
  798. package/docs/architecture/requests/archive/2026/20260528-154740-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
  799. package/docs/architecture/requests/archive/2026/20260528-154816-assets-hooks-assets-hooks-hook-input-sh.md +0 -59
  800. package/docs/architecture/requests/archive/2026/20260528-161851-ai-harness-workflow-contract-json-ai-harness-workflow-contract-json.md +0 -59
  801. package/docs/architecture/requests/archive/2026/20260528-161853-scripts-check-task-workflow-sh-scripts-check-task-workflow-sh.md +0 -59
  802. package/docs/architecture/requests/archive/2026/20260528-161911-assets-workflow-contract-v1-json-assets-workflow-contract-v1-json.md +0 -59
  803. package/docs/architecture/requests/archive/2026/20260528-222416-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
  804. package/docs/architecture/requests/archive/2026/20260528-222444-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
  805. package/docs/architecture/requests/archive/2026/20260528-222457-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
  806. package/docs/architecture/requests/archive/2026/20260528-222648-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
  807. package/docs/architecture/requests/archive/2026/20260528-222705-ai-hooks-ai-hooks-worktree-guard-sh.md +0 -59
  808. package/docs/architecture/requests/archive/2026/20260528-222726-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  809. package/docs/architecture/requests/archive/2026/20260528-222727-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  810. package/docs/architecture/requests/archive/2026/20260528-224736-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
  811. package/docs/architecture/requests/archive/2026/20260528-233259-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  812. package/docs/architecture/requests/archive/2026/20260528-233335-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
  813. package/docs/architecture/requests/archive/2026/20260528-233456-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  814. package/docs/architecture/requests/archive/2026/20260528-233457-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
  815. package/docs/architecture/requests/archive/2026/20260528-233637-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  816. package/docs/architecture/requests/archive/2026/20260528-233638-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
  817. package/docs/architecture/requests/archive/2026/20260529-000322-root-package-json.md +0 -59
  818. package/docs/architecture/requests/archive/2026/20260529-004238-ai-hooks-ai-hooks-lib-workflow-state-sh.md +0 -59
  819. package/docs/architecture/requests/archive/2026/20260529-020654-ai-harness-policy-json-ai-harness-policy-json.md +0 -63
  820. package/docs/architecture/requests/archive/2026/20260529-094236-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -60
  821. package/docs/architecture/requests/archive/2026/20260529-094323-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -60
  822. package/docs/architecture/requests/archive/2026/20260529-094331-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -60
  823. package/docs/architecture/requests/archive/2026/20260529-094339-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -60
  824. package/docs/architecture/requests/archive/2026/20260529-094430-assets-hooks-assets-hooks-session-start-context-sh.md +0 -60
  825. package/docs/architecture/requests/archive/2026/20260529-094446-ai-hooks-ai-hooks-session-start-context-sh.md +0 -60
  826. package/docs/architecture/requests/archive/2026/20260613-002040-runtime-harness-hook-adapters.md +0 -68
  827. package/docs/architecture/requests/archive/2026/root.md +0 -68
  828. package/docs/architecture/requests/archive/2026/runtime-harness-hook-adapters.md +0 -76
  829. package/docs/architecture/requests/archive/2026/verification-evals-checks.md +0 -68
  830. package/docs/architecture/requests/archive/2026/workflow-engine-contract-assets.md +0 -69
  831. package/scripts/archive-architecture-request.sh +0 -4
  832. package/scripts/benchmark-background-check-overlap.ts +0 -228
  833. package/scripts/benchmark-controller-hotpath.ts +0 -212
  834. package/scripts/benchmark-controller-round2.ts +0 -139
  835. package/scripts/benchmark-ios-agent-device.ts +0 -514
  836. package/scripts/benchmark-mcp-host.sh +0 -117
  837. package/scripts/benchmark-mcp-transport.ts +0 -170
  838. package/scripts/benchmark-quality-harness.ts +0 -146
  839. package/scripts/benchmark-route-session-concurrency.ts +0 -915
  840. package/scripts/benchmark-thin-harness-gateway-ab.ts +0 -632
  841. package/scripts/benchmark-thin-harness-mcp-e2e.ts +0 -498
  842. package/scripts/benchmark-thin-harness.ts +0 -251
  843. package/scripts/benchmark-typescript-navigation.ts +0 -186
  844. package/scripts/benchmark-work-efficiency.ts +0 -334
  845. package/scripts/build-controller-ui.ts +0 -28
  846. package/scripts/check-npm-release.sh +0 -32
  847. package/scripts/check-public-release-surface.sh +0 -19
  848. package/scripts/check-release-published.sh +0 -57
  849. package/scripts/check-release-readiness.sh +0 -37
  850. package/scripts/check-release-version.mjs +0 -74
  851. package/scripts/check-tarball-install-smoke.sh +0 -67
  852. package/scripts/package-source-archive.sh +0 -147
  853. package/scripts/public-release-files.txt +0 -39
  854. package/scripts/public-release.ts +0 -174
  855. package/scripts/publish-release-tarball.sh +0 -27
  856. package/scripts/route-nl-vs-ts-eval.ts +0 -679
  857. package/scripts/run-skill-evals.ts +0 -1022
  858. package/scripts/stage-runtime-release.ts +0 -39
  859. package/src/cli/controller/progress.ts +0 -656
  860. package/src/cli/controller/work-mode.ts +0 -181
  861. package/src/cli/local-bridge/console-assets.ts +0 -17
  862. package/src/cli/local-bridge/dashboard.ts +0 -17
  863. package/src/cli/local-bridge/frontend/src/App.tsx +0 -10
  864. package/src/cli/local-bridge/frontend/src/components/Button.tsx +0 -1
  865. package/src/cli/local-bridge/frontend/src/components/DetailPane.tsx +0 -3
  866. package/src/cli/local-bridge/frontend/src/components/SearchField.tsx +0 -1
  867. package/src/cli/local-bridge/frontend/src/components/SectionHeader.tsx +0 -1
  868. package/src/cli/local-bridge/frontend/src/components/Segmented.tsx +0 -1
  869. package/src/cli/local-bridge/frontend/src/components/StatusText.tsx +0 -3
  870. package/src/cli/local-bridge/frontend/src/design/icons.tsx +0 -11
  871. package/src/cli/local-bridge/frontend/src/design/tokens.css +0 -8
  872. package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +0 -153
  873. package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +0 -37
  874. package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +0 -183
  875. package/src/cli/local-bridge/frontend/src/features/repositories/RepositoriesView.tsx +0 -2
  876. package/src/cli/local-bridge/frontend/src/features/system/SystemView.tsx +0 -2
  877. package/src/cli/local-bridge/frontend/src/features/work/WorkView.tsx +0 -4
  878. package/src/cli/local-bridge/frontend/src/lib/api.ts +0 -30
  879. package/src/cli/local-bridge/frontend/src/lib/format.ts +0 -4
  880. package/src/cli/local-bridge/frontend/src/lib/routes.ts +0 -7
  881. package/src/cli/local-bridge/frontend/src/main.tsx +0 -1
  882. package/src/cli/local-bridge/frontend/src/shell/AppShell.tsx +0 -1
  883. package/src/cli/local-bridge/frontend/src/shell/CommandBar.tsx +0 -2
  884. package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +0 -4
  885. package/src/cli/local-bridge/frontend/src/styles.css +0 -28
  886. package/src/cli/local-bridge/frontend/src/types.ts +0 -15
  887. package/src/cli/local-bridge/frontend/src/vite-env.d.ts +0 -1
  888. package/src/cli/local-bridge/frontend/vite.config.ts +0 -27
  889. package/src/cli/local-bridge/ui-dist/app.css +0 -1
  890. package/src/cli/local-bridge/ui-dist/app.js +0 -11228
  891. package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +0 -385
  892. package/src/runtime/control-plane/execution/work-finalization-service.ts +0 -1913
  893. package/src/runtime/control-plane/execution/work-path-scope.ts +0 -37
  894. package/src/runtime/control-plane/execution/work-task-receipt.ts +0 -449
  895. package/src/runtime/control-plane/facade/controller-round-relay.ts +0 -1118
  896. package/src/runtime/control-plane/facade/work-admission-policy.ts +0 -93
  897. package/src/runtime/control-plane/facade/work-task-projection.ts +0 -66
  898. package/src/runtime/control-plane/routing/index.ts +0 -1
  899. package/src/runtime/control-plane/routing/route-policy.ts +0 -382
  900. package/src/runtime/control-plane/routing/workspace-admission.ts +0 -70
@@ -0,0 +1,1167 @@
1
+ import { createHash } from "crypto";
2
+ import { existsSync } from "fs";
3
+ import { join } from "path";
4
+ import { defaultSemanticProviderRegistry, type SemanticNavigationKind, type SemanticNavigationRequest } from "../../../src/runtime/context/semantic-navigation";
5
+ import { buildContextClosureReceipt } from "../../../src/runtime/context/context-closure";
6
+ import { codegraphRepositoryCacheRoot } from "../../../src/runtime/context/codegraph-cache-boundary";
7
+ import type { MultiRepositoryMcpToolContext } from "../multi-repository";
8
+ import { result } from "./result-adapter";
9
+ import { boundedRuntimeResult } from "./bounded-result-runtime";
10
+ import { selected } from "./shared-adapter";
11
+ import { resolveMcpPath } from "../paths";
12
+ import { freshGitIdentity } from "../../../src/cli/repository/inspector";
13
+ import { repositoryCheckoutLifecycle, repositorySummary, resolveRepositorySelection } from "../../../src/cli/repositories/registry";
14
+ import { getExecutionJob, listExecutionJobs } from "../../../src/runtime/execution/jobs/store";
15
+ import { isManagedProcessActive, listProcessRecords, listRecoverableProcessRecords, processRuntimeResourceDiagnostics } from "../../../src/runtime/execution/process-runtime";
16
+ import { CONTROLLER_CONTEXT_IMPACT_DOMAINS, type ControllerContextImpactDomain } from "../../../src/cli/controller/context/types";
17
+ import { buildControllerContextPackInSidecar } from "../../../src/runtime/context/context-pack-process";
18
+ import { listControllerChecks } from "../../../src/cli/controller/check-runner";
19
+ import { getAssistantPluginManifest, getControllerPluginManifest, listAssistantPluginManifests, listControllerPluginManifests } from "../../../src/runtime/plugins/store";
20
+ import { allowedFacadeOperations, buildFacadeResult, listCapabilityDescriptors, getCapabilityDescriptor, getCoreCapabilityExecutionSchema, getPluginActionCapabilitySchema, searchCapabilityDescriptors, summarizeCapabilityGroups, listHandoffAttentionItems, listHandoffItems, normalizeCheckIds, summarizeHandoffItem, buildWorkContinuationSnapshot, getPlanContract, planSemanticView, FACADE_TOOLS } from "../../../src/runtime/control-plane/facade";
21
+ import { currentTaskLineageWorkIds, currentTaskSemanticProjectionForWork, getWorkContract, readActiveWorkCandidates, readWorkContractStore, workSemanticView, type InvalidActiveWorkCandidate, type WorkContract } from "../../../packages/kernel/work/api/index";
22
+ import { readRequirement, requirementSemanticView } from '../../../src/runtime/control-plane/persistence/requirement-store';
23
+ import { readForgeInstanceIdentity, type ScopeRef } from "../../../packages/kernel/identity/api/index";
24
+ import { memoryAddressKey } from "../../../packages/kernel/cognition/api/index";
25
+ import { currentControllerInstanceId } from "../../../src/runtime/control-plane/execution/session-store";
26
+ import { getControllerSession } from "../../../packages/kernel/controller/api/index";
27
+ import { resolveProjectForRepositoryPlacement } from "../../../src/runtime/control-plane/workspace/workspace-store";
28
+ import { cognitiveScopesForWork } from "../../../src/runtime/control-plane/persistence/experience-store";
29
+ import { activateCognitiveMemory, auditCognitiveMemory } from "../../../src/runtime/control-plane/persistence/cognition-store";
30
+ import { cognitiveUsageFeedbackForContext, resolveCognitiveAttention } from "../../../src/runtime/context/cognitive-attention";
31
+ import { invalidFacadeOperation, repositoryExecutionReadiness, summarizeInvalidActiveWorkCandidate, summarizeWorkListItem } from './status-inbox-adapter';
32
+ import type { CallToolResult } from '../../../packages/protocols/mcp/tool-contract';
33
+
34
+ const RH_CONTEXT_RECENT_ACTIVITY_WINDOW_MS = 24 * 60 * 60 * 1_000;
35
+ const RH_CONTEXT_AUTOMATIC_RECALL_LIMIT = 4;
36
+
37
+ function timestampIsRecent(value: string | undefined, cutoffMs: number): boolean {
38
+ if (!value) return false;
39
+ const timestamp = Date.parse(value);
40
+ return Number.isFinite(timestamp) && timestamp >= cutoffMs;
41
+ }
42
+
43
+ const RESUME_CONTEXT_HUMAN_REQUEST_REASONS = new Set([
44
+ 'policy_approval_required',
45
+ 'missing_authorization',
46
+ 'invalid_objective',
47
+ 'destructive_action_requires_confirmation',
48
+ ]);
49
+
50
+ function isRecentRhContextWork(
51
+ contract: Pick<WorkContract, 'semanticState' | 'dispatchState' | 'updatedAt'>,
52
+ cutoffMs: number,
53
+ ): boolean {
54
+ if (contract.semanticState !== 'open') return false;
55
+ if (contract.dispatchState === 'running' || contract.dispatchState === 'launching' || contract.dispatchState === 'claimed') return true;
56
+ return timestampIsRecent(contract.updatedAt, cutoffMs);
57
+ }
58
+
59
+ function rhContextReadSessionId(ctx: MultiRepositoryMcpToolContext): string | undefined {
60
+ const principal = ctx.principalId?.trim();
61
+ if (principal) {
62
+ const controllerInstance = ctx.controllerInstanceId?.trim() || currentControllerInstanceId();
63
+ return `controller:${principal}:${controllerInstance}`;
64
+ }
65
+ const transportSession = ctx.sessionId?.trim();
66
+ return transportSession ? `transport:${transportSession}` : undefined;
67
+ }
68
+
69
+ function rhContextKnowledgeAuditRequested(args: Record<string, unknown>): boolean {
70
+ return [
71
+ 'knowledge_query', 'knowledge_memory_id', 'knowledge_scope_kind', 'knowledge_scope_id',
72
+ 'knowledge_concept', 'knowledge_facet', 'knowledge_source_kind', 'knowledge_source_work_id',
73
+ ].some(key => typeof args[key] === 'string' && String(args[key]).trim().length > 0)
74
+ || typeof args.knowledge_limit === 'number';
75
+ }
76
+
77
+ function rhContextKnowledgeScopes(
78
+ ctx: MultiRepositoryMcpToolContext,
79
+ repository: ReturnType<typeof selected>,
80
+ workId: string | undefined,
81
+ ): { scopes: ScopeRef[]; projectId?: string; gaps: string[] } {
82
+ const store = { controllerHome: ctx.controllerHome, repoId: repository.repoId };
83
+ const work = workId ? getWorkContract(store, workId) : undefined;
84
+ if (work) {
85
+ const scopes = cognitiveScopesForWork(work, ctx.controllerHome);
86
+ return { scopes, projectId: scopes.find(scope => scope.kind === 'project')?.id, gaps: [] };
87
+ }
88
+ const instance = readForgeInstanceIdentity(ctx.controllerHome);
89
+ if (!instance) return { scopes: [], gaps: ['forge_instance_identity_unavailable'] };
90
+ const project = resolveProjectForRepositoryPlacement({
91
+ controllerHome: ctx.controllerHome,
92
+ forgeInstanceId: instance.instanceId,
93
+ repositoryId: repository.repoId,
94
+ checkoutId: repository.activeCheckoutId,
95
+ });
96
+ if (!project) return { scopes: [], gaps: ['project_placement_unavailable'] };
97
+ return {
98
+ projectId: project.projectId,
99
+ scopes: [
100
+ { schemaVersion: 1, kind: 'project', id: project.projectId },
101
+ { schemaVersion: 1, kind: 'workspace', id: project.workspaceId },
102
+ ],
103
+ gaps: [],
104
+ };
105
+ }
106
+
107
+ function rhContextKnowledgeAudit(
108
+ ctx: MultiRepositoryMcpToolContext,
109
+ repository: ReturnType<typeof selected>,
110
+ args: Record<string, unknown>,
111
+ ): Record<string, unknown> {
112
+ const workId = typeof args.work_id === 'string' && args.work_id.trim() ? args.work_id.trim() : undefined;
113
+ const resolved = rhContextKnowledgeScopes(ctx, repository, workId);
114
+ const requestedKind = typeof args.knowledge_scope_kind === 'string' ? args.knowledge_scope_kind.trim() : '';
115
+ const requestedId = typeof args.knowledge_scope_id === 'string' ? args.knowledge_scope_id.trim() : '';
116
+ const scopes = resolved.scopes.filter(scope =>
117
+ (!requestedKind || scope.kind === requestedKind) && (!requestedId || scope.id === requestedId));
118
+ const scopeMismatch = resolved.scopes.length > 0 && scopes.length === 0 && Boolean(requestedKind || requestedId);
119
+ const rawQuery = typeof args.knowledge_query === 'string' ? args.knowledge_query.trim() : '';
120
+ const query = rawQuery === '*' ? '' : rawQuery;
121
+ const audit = auditCognitiveMemory(ctx.controllerHome, {
122
+ scopes,
123
+ ...(query ? { query } : {}),
124
+ ...(typeof args.knowledge_memory_id === 'string' && args.knowledge_memory_id.trim()
125
+ ? { memoryId: args.knowledge_memory_id.trim() } : {}),
126
+ ...(typeof args.knowledge_concept === 'string' && args.knowledge_concept.trim()
127
+ ? { concept: args.knowledge_concept.trim() } : {}),
128
+ ...(typeof args.knowledge_facet === 'string' && args.knowledge_facet.trim()
129
+ ? { facet: args.knowledge_facet.trim() } : {}),
130
+ ...(typeof args.knowledge_source_kind === 'string' && args.knowledge_source_kind.trim()
131
+ ? { sourceKind: args.knowledge_source_kind.trim() as 'experience' | 'outcome' | 'knowledge' | 'controller' | 'system' | 'external' } : {}),
132
+ ...(typeof args.knowledge_source_work_id === 'string' && args.knowledge_source_work_id.trim()
133
+ ? { sourceWorkId: args.knowledge_source_work_id.trim() } : {}),
134
+ ...(typeof args.knowledge_limit === 'number' ? { limit: args.knowledge_limit } : {}),
135
+ });
136
+ const usage = cognitiveUsageFeedbackForContext({
137
+ controllerHome: ctx.controllerHome,
138
+ repoId: repository.repoId,
139
+ scopes,
140
+ ...(resolved.projectId ? { projectId: resolved.projectId } : {}),
141
+ });
142
+ const usageByAddress = new Map(usage.map(item => [memoryAddressKey(item.address), item]));
143
+ const activation = query
144
+ ? activateCognitiveMemory(ctx.controllerHome, scopes, query, {
145
+ maxItems: Math.min(32, Math.max(1, typeof args.knowledge_limit === 'number' ? Math.trunc(args.knowledge_limit) : 24)),
146
+ usageFeedback: usage,
147
+ })
148
+ : undefined;
149
+ const activationByAddress = new Map((activation?.items ?? []).map(item => [
150
+ memoryAddressKey({ scope: item.memory.scope, id: item.memory.id }),
151
+ { score: item.score, reasons: item.reasons, activationPath: item.activationPath },
152
+ ]));
153
+ return {
154
+ readonly: true,
155
+ advisoryOnly: true,
156
+ authorityBoundary: 'Learned memory never overrides project contracts, authorization, verification, Requirement/Plan/Work, or semantic acceptance.',
157
+ scopes,
158
+ filters: {
159
+ ...(rawQuery ? { query: rawQuery } : {}),
160
+ ...(requestedKind ? { scopeKind: requestedKind } : {}),
161
+ ...(requestedId ? { scopeId: requestedId } : {}),
162
+ ...(typeof args.knowledge_memory_id === 'string' && args.knowledge_memory_id.trim() ? { memoryId: args.knowledge_memory_id.trim() } : {}),
163
+ ...(typeof args.knowledge_concept === 'string' && args.knowledge_concept.trim() ? { concept: args.knowledge_concept.trim() } : {}),
164
+ ...(typeof args.knowledge_facet === 'string' && args.knowledge_facet.trim() ? { facet: args.knowledge_facet.trim() } : {}),
165
+ ...(typeof args.knowledge_source_kind === 'string' && args.knowledge_source_kind.trim() ? { sourceKind: args.knowledge_source_kind.trim() } : {}),
166
+ ...(typeof args.knowledge_source_work_id === 'string' && args.knowledge_source_work_id.trim() ? { sourceWorkId: args.knowledge_source_work_id.trim() } : {}),
167
+ },
168
+ items: audit.items.map(entry => {
169
+ const address = memoryAddressKey({ scope: entry.memory.scope, id: entry.memory.id });
170
+ return {
171
+ memory: entry.memory,
172
+ relations: entry.relations,
173
+ recentUsage: usageByAddress.get(address),
174
+ activation: activationByAddress.get(address),
175
+ };
176
+ }),
177
+ inspected: audit.inspected,
178
+ truncated: audit.truncated,
179
+ gaps: [...resolved.gaps, ...(scopeMismatch ? ['requested_cognitive_scope_not_reachable'] : [])],
180
+ };
181
+ }
182
+
183
+ function rhContextLearningRecall(
184
+ ctx: MultiRepositoryMcpToolContext,
185
+ repository: ReturnType<typeof selected>,
186
+ query: string,
187
+ workId?: string,
188
+ limit = RH_CONTEXT_AUTOMATIC_RECALL_LIMIT,
189
+ ): Record<string, unknown> {
190
+ const resolved = rhContextKnowledgeScopes(ctx, repository, workId);
191
+ if (!query.trim() || resolved.scopes.length === 0) {
192
+ return { advisoryOnly: true, scopes: resolved.scopes, items: [], gaps: resolved.gaps };
193
+ }
194
+ const usage = cognitiveUsageFeedbackForContext({
195
+ controllerHome: ctx.controllerHome,
196
+ repoId: repository.repoId,
197
+ scopes: resolved.scopes,
198
+ ...(resolved.projectId ? { projectId: resolved.projectId } : {}),
199
+ });
200
+ const activation = resolveCognitiveAttention({
201
+ controllerHome: ctx.controllerHome,
202
+ scopes: resolved.scopes,
203
+ query: query.slice(0, 4_000),
204
+ now: new Date().toISOString(),
205
+ maxItems: Math.min(8, Math.max(1, limit)),
206
+ maxBytes: 12 * 1024,
207
+ usageFeedback: usage,
208
+ });
209
+ return {
210
+ advisoryOnly: true,
211
+ authorityBoundary: 'Learned context may guide model decisions but never grants execution, lifecycle, or acceptance authority.',
212
+ scopePolicy: 'unified_relevance_with_narrow_scope_prior',
213
+ scopes: resolved.scopes,
214
+ items: activation.items.map(entry => ({
215
+ memoryId: memoryAddressKey({ scope: entry.memory.scope, id: entry.memory.id }),
216
+ text: entry.memory.canonicalText,
217
+ score: entry.score,
218
+ reasons: entry.reasons,
219
+ activationPath: entry.activationPath,
220
+ facets: entry.memory.facets,
221
+ concepts: entry.memory.concepts,
222
+ provenance: entry.memory.provenance,
223
+ })),
224
+ gaps: [...resolved.gaps, ...activation.gaps],
225
+ progressiveAttention: {
226
+ workingSetBounded: true,
227
+ moreCandidatesAvailable: activation.truncated,
228
+ inspectedCandidates: activation.inspectedCandidates,
229
+ modelDecision: activation.truncated
230
+ ? 'This is an initial working set, not semantic completeness. If the current decision still lacks relevant prior context, issue a narrower rh_context query or an explicit knowledge_query/knowledge_limit expansion; otherwise reuse this working set through routine micro-steps.'
231
+ : 'Decide whether this working set is semantically sufficient. Reuse it through routine micro-steps; only recall again when the task meaning/strategy changes or missing prior context could change the decision.',
232
+ },
233
+ };
234
+ }
235
+
236
+ const RH_CONTEXT_SEMANTIC_QUERY_LIMIT = 8;
237
+
238
+ const RH_CONTEXT_SEMANTIC_LOCATION_LIMIT = 200;
239
+
240
+ const RH_CONTEXT_LEGACY_SEMANTIC_SYNTAX = '@tsnav references <repo-path>:<line>:<column> | @swiftnav references <repo-path>:<line>:<column>';
241
+
242
+ type RhContextSemanticNavigationRequest = {
243
+ navigation: SemanticNavigationKind;
244
+ path: string;
245
+ line: number;
246
+ column: number;
247
+ tsconfig_path?: string;
248
+ language?: string;
249
+ };
250
+
251
+ function rhContextLegacySemanticQuery(query: string): {
252
+ retrievalQuery: string;
253
+ requests: RhContextSemanticNavigationRequest[];
254
+ } {
255
+ const requests: RhContextSemanticNavigationRequest[] = [];
256
+ const directive = /(?:^|\s)@(tsnav|swiftnav)\s+(definition|references|implementations)\s+([^\s]+):(\d+):(\d+)(?:\s+tsconfig=([^\s]+))?/gi;
257
+ const retrievalQuery = query.replace(directive, (_match, directiveKind, navigation, path, line, column, tsconfigPath) => {
258
+ const language = String(directiveKind).toLowerCase() === 'swiftnav' ? 'swift' : 'typescript';
259
+ requests.push({
260
+ navigation: String(navigation).toLowerCase() as SemanticNavigationKind,
261
+ path: String(path),
262
+ line: Number(line),
263
+ column: Number(column),
264
+ language,
265
+ ...(tsconfigPath ? { tsconfig_path: String(tsconfigPath) } : {}),
266
+ });
267
+ return ' ';
268
+ }).replace(/\s+/g, ' ').trim();
269
+ const fallback = requests.length > 0
270
+ ? `${requests[0]!.language === 'swift' ? 'Swift' : 'TypeScript'} ${requests[0]!.navigation} ${requests[0]!.path}`
271
+ : query;
272
+ return { retrievalQuery: retrievalQuery || fallback, requests };
273
+ }
274
+
275
+ interface RhContextSemanticNavigationProjection {
276
+ requested: number;
277
+ executed: number;
278
+ results: Record<string, unknown>[];
279
+ errors: Array<{ index: number; code: string; message: string }>;
280
+ providers: unknown[];
281
+ policyDeniedLocations: number;
282
+ policyDeniedReads: number;
283
+ policyDeniedReadSamples: string[];
284
+ requestTruncated: boolean;
285
+ freshness: 'not_requested' | 'changed_during_query' | 'current_at_query';
286
+ sourceIdentity?: Record<string, unknown>;
287
+ staticClosure: { scope: string; status: 'not_requested' | 'incomplete' | 'complete_for_requested_symbols'; limitations: string[] };
288
+ }
289
+
290
+ async function rhContextSemanticNavigation(
291
+ repoRoot: string,
292
+ policy: MultiRepositoryMcpToolContext['policy'],
293
+ value: unknown,
294
+ repositoryIdentity: { repoId: string; checkoutId: string },
295
+ ): Promise<RhContextSemanticNavigationProjection> {
296
+ const raw = Array.isArray(value) ? value : [];
297
+ const requests = raw.slice(0, RH_CONTEXT_SEMANTIC_QUERY_LIMIT);
298
+ const results: Record<string, unknown>[] = [];
299
+ const errors: Array<{ index: number; code: string; message: string }> = [];
300
+ let anyLocationTruncated = false;
301
+ let policyDeniedLocations = 0;
302
+ let policyDeniedReads = 0;
303
+ const policyDeniedReadSamples = new Set<string>();
304
+ const semanticAccessScope = createHash('sha256')
305
+ .update(JSON.stringify({ profile: policy.profile, readGlobs: policy.readGlobs, denyGlobs: policy.denyGlobs }))
306
+ .digest('hex')
307
+ .slice(0, 20);
308
+
309
+ const fingerprintOf = (identity: ReturnType<typeof freshGitIdentity> | undefined): string | undefined => identity
310
+ ? identity.workingTreeFingerprint
311
+ ?? createHash('sha256').update(`${identity.head ?? ''}\n${identity.branch ?? ''}`).digest('hex').slice(0, 24)
312
+ : undefined;
313
+ // Semantic providers are targeted/optional, so pay the stronger fresh identity
314
+ // sampling cost only when semantic evidence was explicitly requested.
315
+ const sourceBefore = requests.length > 0 ? freshGitIdentity(repoRoot) : undefined;
316
+ const sourceFingerprintBefore = fingerprintOf(sourceBefore);
317
+ const indexedRequests: Array<{ index: number; request: SemanticNavigationRequest }> = [];
318
+
319
+ requests.forEach((entry, index) => {
320
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
321
+ errors.push({ index, code: 'SEMANTIC_NAVIGATION_REQUEST_INVALID', message: 'semantic_navigation entries must be objects.' });
322
+ return;
323
+ }
324
+ const item = entry as Record<string, unknown>;
325
+ const navigation = String(item.navigation ?? '') as SemanticNavigationKind;
326
+ const path = String(item.path ?? '').trim();
327
+ const line = Number(item.line);
328
+ const column = Number(item.column);
329
+ const tsconfigPath = typeof item.tsconfig_path === 'string' && item.tsconfig_path.trim() ? item.tsconfig_path.trim() : undefined;
330
+ const language = typeof item.language === 'string' && item.language.trim() ? item.language.trim().toLowerCase() : undefined;
331
+ if (!['definition', 'references', 'implementations'].includes(navigation) || !path || !Number.isInteger(line) || line < 1 || !Number.isInteger(column) || column < 1) {
332
+ errors.push({ index, code: 'SEMANTIC_NAVIGATION_REQUEST_INVALID', message: 'navigation, path, and positive 1-based line/column are required.' });
333
+ return;
334
+ }
335
+ const targetDecision = resolveMcpPath(repoRoot, path, policy, 'read');
336
+ if (!targetDecision.ok) {
337
+ errors.push({ index, code: 'SEMANTIC_NAVIGATION_TARGET_DENIED', message: targetDecision.reason ?? 'target path denied by MCP read policy.' });
338
+ return;
339
+ }
340
+ indexedRequests.push({
341
+ index,
342
+ request: { navigation, path, line, column, ...(tsconfigPath ? { tsconfigPath } : {}), ...(language ? { language } : {}) },
343
+ });
344
+ });
345
+
346
+ const allowRepositoryPath = (relativePath: string): boolean => {
347
+ const decision = resolveMcpPath(repoRoot, relativePath, policy, 'read');
348
+ if (decision.ok) return true;
349
+ policyDeniedReads += 1;
350
+ if (policyDeniedReadSamples.size < 20) policyDeniedReadSamples.add(relativePath);
351
+ return false;
352
+ };
353
+
354
+ const navigationOutcomes = await defaultSemanticProviderRegistry.navigate(repoRoot, indexedRequests, {
355
+ cacheScope: `mcp:${semanticAccessScope}`,
356
+ sourceIdentity: sourceFingerprintBefore,
357
+ profile: policy.profile,
358
+ readPolicy: {
359
+ profile: policy.profile,
360
+ readGlobs: [...policy.readGlobs],
361
+ denyGlobs: [...policy.denyGlobs],
362
+ maxFileBytes: policy.maxFileBytes,
363
+ },
364
+ allowRepositoryPath,
365
+ });
366
+
367
+ for (const { index, outcome } of navigationOutcomes) {
368
+ if (!outcome.ok) {
369
+ errors.push({ index, code: outcome.code, message: outcome.message });
370
+ continue;
371
+ }
372
+ const semantic = outcome.result;
373
+ const sidecarDeniedReads = Math.max(0, Number(semantic.policyDeniedReads ?? 0));
374
+ policyDeniedReads += sidecarDeniedReads;
375
+ const sidecarDeniedSamples = semantic.details?.policyDeniedReadSamples;
376
+ if (Array.isArray(sidecarDeniedSamples)) {
377
+ for (const sample of sidecarDeniedSamples) {
378
+ if (policyDeniedReadSamples.size >= 20) break;
379
+ if (typeof sample === 'string' && sample.trim()) policyDeniedReadSamples.add(sample);
380
+ }
381
+ }
382
+ const allowedLocations = semantic.locations.filter((location) => {
383
+ const decision = resolveMcpPath(repoRoot, location.path, policy, 'read');
384
+ if (decision.ok) return true;
385
+ policyDeniedLocations += 1;
386
+ return false;
387
+ });
388
+ const truncated = allowedLocations.length > RH_CONTEXT_SEMANTIC_LOCATION_LIMIT;
389
+ anyLocationTruncated ||= truncated;
390
+ results.push({
391
+ provider: semantic.providerId,
392
+ ...(semantic.providerIdentity ? { providerIdentity: semantic.providerIdentity } : {}),
393
+ language: semantic.language,
394
+ navigation: semantic.navigation,
395
+ target: semantic.target,
396
+ locations: allowedLocations.slice(0, RH_CONTEXT_SEMANTIC_LOCATION_LIMIT),
397
+ totalLocations: allowedLocations.length,
398
+ returnedLocations: Math.min(allowedLocations.length, RH_CONTEXT_SEMANTIC_LOCATION_LIMIT),
399
+ truncated,
400
+ policyDeniedReads: semantic.policyDeniedReads ?? 0,
401
+ ...(semantic.details ?? {}),
402
+ });
403
+ }
404
+
405
+ results.sort((left, right) => {
406
+ const leftTarget = left.target as { path?: string; line?: number; column?: number } | undefined;
407
+ const rightTarget = right.target as { path?: string; line?: number; column?: number } | undefined;
408
+ return String(leftTarget?.path ?? '').localeCompare(String(rightTarget?.path ?? ''))
409
+ || Number(leftTarget?.line ?? 0) - Number(rightTarget?.line ?? 0)
410
+ || Number(leftTarget?.column ?? 0) - Number(rightTarget?.column ?? 0);
411
+ });
412
+
413
+ const sourceAfter = requests.length > 0 ? freshGitIdentity(repoRoot) : undefined;
414
+ const sourceFingerprintAfter = fingerprintOf(sourceAfter);
415
+ const sourceChangedDuringQuery = Boolean(
416
+ sourceBefore
417
+ && sourceAfter
418
+ && (sourceBefore.head !== sourceAfter.head || sourceFingerprintBefore !== sourceFingerprintAfter),
419
+ );
420
+ if (sourceChangedDuringQuery) {
421
+ errors.push({
422
+ index: -1,
423
+ code: 'SEMANTIC_SOURCE_CHANGED_DURING_QUERY',
424
+ message: 'Repository source identity changed while semantic providers were running. Returned locations are retained only as hints for the sampled source and are not proof for the newer source state.',
425
+ });
426
+ }
427
+
428
+ const requestTruncated = raw.length > RH_CONTEXT_SEMANTIC_QUERY_LIMIT;
429
+ const incomplete = requestTruncated || anyLocationTruncated || policyDeniedLocations > 0 || policyDeniedReads > 0 || errors.length > 0 || sourceChangedDuringQuery;
430
+ const languages = new Set(results.map((entry) => String(entry.language ?? '')).filter(Boolean));
431
+ const singleLanguage = languages.size === 1 ? [...languages][0] : undefined;
432
+ const scope = singleLanguage === 'typescript'
433
+ ? 'requested_typescript_static_relationships'
434
+ : singleLanguage === 'swift'
435
+ ? 'requested_swift_static_relationships'
436
+ : singleLanguage
437
+ ? `requested_${singleLanguage.replace(/[^a-z0-9_-]+/gi, '_').toLowerCase()}_static_relationships`
438
+ : languages.size > 1
439
+ ? 'requested_multilanguage_static_relationships'
440
+ : 'requested_semantic_static_relationships';
441
+ return {
442
+ requested: raw.length,
443
+ executed: requests.length,
444
+ results,
445
+ errors,
446
+ providers: defaultSemanticProviderRegistry.list(),
447
+ policyDeniedLocations,
448
+ policyDeniedReads,
449
+ policyDeniedReadSamples: Array.from(policyDeniedReadSamples),
450
+ requestTruncated,
451
+ freshness: raw.length === 0 ? 'not_requested' : sourceChangedDuringQuery ? 'changed_during_query' : 'current_at_query',
452
+ ...(sourceBefore ? {
453
+ sourceIdentity: {
454
+ repoId: repositoryIdentity.repoId,
455
+ checkoutId: repositoryIdentity.checkoutId,
456
+ branch: sourceBefore.branch,
457
+ head: sourceBefore.head,
458
+ workingTreeFingerprint: sourceFingerprintBefore,
459
+ sampledAt: new Date(sourceBefore.sampledAt).toISOString(),
460
+ },
461
+ } : {}),
462
+ staticClosure: {
463
+ scope,
464
+ status: raw.length === 0 ? 'not_requested' : incomplete ? 'incomplete' : 'complete_for_requested_symbols',
465
+ limitations: ['dynamic_registration', 'string_or_config_edges', 'reflection', 'runtime_dispatch', 'stale_or_missing_language_index'],
466
+ },
467
+ };
468
+ }
469
+
470
+ function codegraphIndexExists(controllerHome: string, root: string): boolean {
471
+ return existsSync(join(codegraphRepositoryCacheRoot(controllerHome, root), 'codegraph.db'))
472
+ || existsSync(join(root, '.codegraph', 'codegraph.db'));
473
+ }
474
+
475
+ /**
476
+ * Managed worktrees borrow one repository baseline CodeGraph from a non-worktree
477
+ * checkout. Dirty worktree bytes remain a raw/lexical overlay; they never create
478
+ * a second structural-index authority merely because execution is isolated.
479
+ * Repo-local `.codegraph` is retained only as a legacy-readable fallback.
480
+ */
481
+ export function resolveStructuralIndexRoot(
482
+ controllerHome: string,
483
+ repository: ReturnType<typeof resolveRepositorySelection>,
484
+ ): string | undefined {
485
+ const active = repository.checkouts.find((checkout) => checkout.checkoutId === repository.activeCheckoutId);
486
+ const nonWorktreeRoots = repository.checkouts
487
+ .filter((checkout) => checkout.checkoutId !== repository.activeCheckoutId && checkout.worktree !== true && repositoryCheckoutLifecycle(checkout) === 'active')
488
+ .map((checkout) => checkout.canonicalRoot);
489
+ const candidates = active?.worktree === true
490
+ ? [...nonWorktreeRoots, repository.canonicalRoot]
491
+ : [repository.canonicalRoot, ...nonWorktreeRoots];
492
+ return [...new Set(candidates)].find((root) => codegraphIndexExists(controllerHome, root));
493
+ }
494
+
495
+ export async function callContextAdapter(ctx: MultiRepositoryMcpToolContext, name: string, args: Record<string, unknown>): Promise<CallToolResult | undefined> {
496
+ if (name !== 'rh_context') return undefined;
497
+ const repository = selected(ctx, args);
498
+ const operation = String(args.operation ?? 'get');
499
+ if (!allowedFacadeOperations('rh_context').includes(operation)) {
500
+ return invalidFacadeOperation('rh_context', operation);
501
+ }
502
+ if (operation === 'search') {
503
+ const query = typeof args.query === 'string' ? args.query.trim() : '';
504
+ const knowledgeAuditRequested = rhContextKnowledgeAuditRequested(args);
505
+ if (!query && !knowledgeAuditRequested) {
506
+ const facade = buildFacadeResult({
507
+ status: 'failed',
508
+ summary: 'rh_context.search requires a non-empty code query or explicit knowledge audit fields.',
509
+ data: { operation, repoId: repository.repoId },
510
+ suggestedNextActions: [],
511
+ });
512
+ return result(facade as unknown as Record<string, unknown>, true);
513
+ }
514
+ const cognitionAudit = knowledgeAuditRequested ? rhContextKnowledgeAudit(ctx, repository, args) : undefined;
515
+ const includeLearningRecall = args.include_learning_recall !== false;
516
+ const learningRecall = query && !knowledgeAuditRequested && includeLearningRecall
517
+ ? rhContextLearningRecall(ctx, repository, query, typeof args.work_id === 'string' ? args.work_id.trim() || undefined : undefined)
518
+ : undefined;
519
+ if (!query && cognitionAudit) {
520
+ const items = Array.isArray(cognitionAudit.items) ? cognitionAudit.items : [];
521
+ const facade = buildFacadeResult({
522
+ status: 'ok',
523
+ summary: `Retrieved ${items.length} bounded learned-memory audit item(s).`,
524
+ data: { operation, repoId: repository.repoId, cognitionAudit },
525
+ warnings: [],
526
+ suggestedNextActions: [],
527
+ detailLevel: args.detail_level === 'detail' || args.detail_level === 'raw' ? args.detail_level : 'summary',
528
+ rawAvailable: false,
529
+ });
530
+ // cognitionAudit is already bounded by scope/item/relation/usage/activation budgets.
531
+ // Preserve its nested provenance and reasoning rather than letting generic facade depth
532
+ // bounding turn the read-only audit contract into opaque "[bounded-depth]" markers.
533
+ (facade.data as typeof facade.data & { cognitionAudit: typeof cognitionAudit }).cognitionAudit = cognitionAudit;
534
+ return result(facade as unknown as Record<string, unknown>);
535
+ }
536
+ const legacySemanticQuery = rhContextLegacySemanticQuery(query);
537
+ const retrievalQuery = legacySemanticQuery.retrievalQuery;
538
+ const list = (value: unknown): string[] => Array.isArray(value)
539
+ ? value.map(String).map((entry) => entry.trim()).filter(Boolean)
540
+ : [];
541
+ const retrievalMode = args.retrieval_mode === 'plan' || args.retrieval_mode === 'debug' || args.retrieval_mode === 'review'
542
+ ? args.retrieval_mode
543
+ : 'implementation';
544
+ const impactDomains = list(args.impact_domains)
545
+ .filter((domain): domain is ControllerContextImpactDomain => CONTROLLER_CONTEXT_IMPACT_DOMAINS.includes(domain as ControllerContextImpactDomain));
546
+ const structuralContext = args.structural_context === 'off' || args.structural_context === 'auto' || args.structural_context === 'required'
547
+ ? args.structural_context
548
+ : retrievalMode === 'plan' || retrievalMode === 'debug'
549
+ ? 'required'
550
+ : 'auto';
551
+ const requestedCheckIds = list(args.requested_check_ids);
552
+ // Source retrieval is the default Context responsibility. Check
553
+ // readiness is only meaningful when the controller has named the
554
+ // checks it is about to use, so do not pay its Git/dependency/schedule
555
+ // preflight cost for every broad search.
556
+ const checks = requestedCheckIds.length > 0
557
+ ? listControllerChecks(repository.canonicalRoot)
558
+ : [];
559
+ const executionReadiness = requestedCheckIds.length > 0
560
+ ? repositoryExecutionReadiness(repository.canonicalRoot, checks, requestedCheckIds, {
561
+ repoId: repository.repoId,
562
+ checkoutId: repository.activeCheckoutId,
563
+ })
564
+ : undefined;
565
+ const pack = await buildControllerContextPackInSidecar({
566
+ repoRoot: repository.canonicalRoot,
567
+ policy: ctx.policy,
568
+ options: {
569
+ description: retrievalQuery,
570
+ // Short code-like queries remain useful exact lexical needles. Long
571
+ // semantic prompts are already tokenized from description; adding the
572
+ // whole prompt as an exact needle prevents batch-search early exit and
573
+ // forces a full bounded repository scan for a phrase that will not match.
574
+ searchTerms: retrievalQuery.length <= 160 ? [retrievalQuery] : undefined,
575
+ knownPaths: list(args.known_paths),
576
+ includeGlobs: list(args.include_globs),
577
+ excludeGlobs: list(args.exclude_globs),
578
+ maxFiles: typeof args.max_files === 'number' ? args.max_files : undefined,
579
+ maxSnippets: typeof args.max_snippets === 'number' ? args.max_snippets : undefined,
580
+ structuralContext,
581
+ structuralIndexRoot: structuralContext === 'off' ? undefined : resolveStructuralIndexRoot(ctx.controllerHome, repository),
582
+ retrievalMode,
583
+ impactDomains,
584
+ session: rhContextReadSessionId(ctx)
585
+ ? { sessionId: rhContextReadSessionId(ctx)!, repoId: repository.repoId, checkoutId: repository.activeCheckoutId }
586
+ : undefined,
587
+ },
588
+ });
589
+ const explicitSemanticNavigation = Array.isArray(args.semantic_navigation) ? args.semantic_navigation : [];
590
+ const semanticRequests = [...explicitSemanticNavigation, ...legacySemanticQuery.requests];
591
+ const semanticNavigation = {
592
+ ...await rhContextSemanticNavigation(repository.canonicalRoot, ctx.policy, semanticRequests, { repoId: repository.repoId, checkoutId: repository.activeCheckoutId }),
593
+ requestSource: explicitSemanticNavigation.length > 0 && legacySemanticQuery.requests.length > 0
594
+ ? 'schema_and_query'
595
+ : explicitSemanticNavigation.length > 0
596
+ ? 'semantic_navigation'
597
+ : legacySemanticQuery.requests.length > 0
598
+ ? 'query_compatibility'
599
+ : 'none',
600
+ compatibilityQuerySyntax: RH_CONTEXT_LEGACY_SEMANTIC_SYNTAX,
601
+ };
602
+ const semanticReasonCodes = Array.from(new Set([
603
+ ...semanticNavigation.errors.map((entry) => `semantic.${String(entry.code ?? 'provider_error').toLowerCase()}`),
604
+ ...(semanticNavigation.requestTruncated ? ['semantic.request_truncated'] : []),
605
+ ...(semanticNavigation.policyDeniedLocations > 0 || semanticNavigation.policyDeniedReads > 0 ? ['semantic.policy_denied'] : []),
606
+ ...(semanticNavigation.freshness === 'changed_during_query' ? ['semantic.source_changed_during_query'] : []),
607
+ ...(semanticNavigation.requested > 0 && semanticNavigation.staticClosure.status !== 'complete_for_requested_symbols' ? ['semantic.static_closure_incomplete'] : []),
608
+ ]));
609
+ const semanticUnavailable = semanticNavigation.requested > 0
610
+ && semanticNavigation.results.length === 0
611
+ && semanticNavigation.errors.length > 0
612
+ && semanticNavigation.errors.every((entry) => /UNAVAILABLE|NOT_AVAILABLE|NOT_READY|MISSING|NOT_FOUND|BUILD_SETTINGS|BUILD_SERVER/i.test(String(entry.code ?? '')));
613
+ const semanticReadinessStatus = semanticNavigation.requested === 0
614
+ ? 'not_requested' as const
615
+ : semanticNavigation.results.length === 0 && semanticNavigation.errors.length > 0
616
+ ? semanticUnavailable ? 'unavailable' as const : 'error' as const
617
+ : semanticNavigation.staticClosure.status === 'complete_for_requested_symbols' && semanticReasonCodes.length === 0
618
+ ? 'ready' as const
619
+ : 'partial' as const;
620
+ const readinessStatus = pack.readiness.status === 'insufficient'
621
+ ? 'insufficient' as const
622
+ : semanticReadinessStatus === 'unavailable' || semanticReadinessStatus === 'error'
623
+ ? 'insufficient' as const
624
+ : pack.readiness.status === 'degraded' || semanticReadinessStatus === 'partial'
625
+ ? 'degraded' as const
626
+ : 'ready' as const;
627
+ const readiness = {
628
+ ...pack.readiness,
629
+ status: readinessStatus,
630
+ semantic: { status: semanticReadinessStatus, reasonCodes: semanticReasonCodes },
631
+ unresolvedReasonCodes: Array.from(new Set([...pack.readiness.unresolvedReasonCodes, ...semanticReasonCodes])).slice(0, 80),
632
+ readyForHighConfidenceMutation: readinessStatus === 'ready',
633
+ };
634
+ const closureWorkId = typeof args.work_id === 'string' ? args.work_id.trim() : '';
635
+ const closureWork = closureWorkId
636
+ ? getWorkContract({ controllerHome: ctx.controllerHome, repoId: repository.repoId }, closureWorkId)
637
+ : undefined;
638
+ const contextClosure = buildContextClosureReceipt({
639
+ repoRoot: repository.canonicalRoot,
640
+ query: retrievalQuery,
641
+ pack: { ...pack, readiness },
642
+ semanticNavigation,
643
+ semanticProviders: defaultSemanticProviderRegistry.list(),
644
+ workId: closureWorkId || undefined,
645
+ activeWorkIds: closureWork ? [closureWork.workId] : [],
646
+ includeRecentChanges: retrievalMode !== 'implementation',
647
+ });
648
+ const warnings = structuralContext === 'required' && !pack.structuralContext.requiredSatisfied
649
+ ? [pack.structuralContext.fallbackReason ?? 'Required structural context is not ready; lexical retrieval results are returned as degraded evidence.']
650
+ : [];
651
+ const facade = buildFacadeResult({
652
+ status: 'ok',
653
+ summary: pack.files.length
654
+ ? `Retrieved ${pack.files.length} bounded code context file(s) for the query.`
655
+ : 'No bounded code context matched the query.',
656
+ data: {
657
+ operation,
658
+ repoId: repository.repoId,
659
+ goal: pack.goal,
660
+ search: pack.search,
661
+ structuralContext: pack.structuralContext,
662
+ impactContext: pack.impactContext,
663
+ semanticNavigation,
664
+ contextClosure,
665
+ readiness,
666
+ expansion: pack.expansion,
667
+ files: pack.files,
668
+ coverage: pack.coverage,
669
+ cache: pack.cache,
670
+ timingsMs: pack.timingsMs,
671
+ deniedPaths: pack.deniedPaths,
672
+ omitted: pack.omitted,
673
+ limits: pack.limits,
674
+ contextContract: pack.contextContract,
675
+ ...(cognitionAudit ? { cognitionAudit } : {}),
676
+ ...(learningRecall ? { learningRecall } : {}),
677
+ ...(executionReadiness ? {
678
+ executionReadiness,
679
+ registeredChecks: checks.slice(0, 80).map((check) => ({ id: check.id, description: check.description, source: check.source, effects: check.effects })),
680
+ } : {}),
681
+ retrievalPolicy: {
682
+ defaultBackend: 'bounded_lexical',
683
+ structuralBackend: 'codegraph',
684
+ rawReadTool: 'read_repository_file',
685
+ shellSearchFallbackOnly: true,
686
+ executionReadiness: 'requested_check_ids_only',
687
+ },
688
+ },
689
+ warnings,
690
+ suggestedNextActions: [],
691
+ detailLevel: args.detail_level === 'detail' || args.detail_level === 'raw' ? args.detail_level : 'summary',
692
+ rawAvailable: true,
693
+ });
694
+ // ContextClosureReceipt already enforces bounded paths, tests, skills, semantic providers,
695
+ // and reason codes. Generic facade depth bounding is appropriate for exploratory context,
696
+ // but it must not corrupt this runtime-issued round-trip contract because rh_work validates
697
+ // the exact full receipt digest supplied by the Controller during engineering re-entry.
698
+ (facade.data as typeof facade.data & { contextClosure: typeof contextClosure }).contextClosure = contextClosure;
699
+ // Individual snippets are bounded, but broad searches can still aggregate
700
+ // a very large direct MCP payload. Keep ContextClosure authority inline and
701
+ // externalize only the heavy file collection through the existing Result Store.
702
+ const boundedFiles = boundedRuntimeResult({
703
+ controllerHome: ctx.controllerHome,
704
+ repoId: repository.repoId,
705
+ sessionId: ctx.sessionId,
706
+ principalId: ctx.principalId,
707
+ controllerInstanceId: ctx.controllerInstanceId,
708
+ workId: typeof args.work_id === 'string' ? args.work_id.trim() || undefined : undefined,
709
+ }, pack.files);
710
+ const data = facade.data as typeof facade.data & {
711
+ files: typeof pack.files;
712
+ filesResult?: unknown;
713
+ filesTruncated?: boolean;
714
+ fileCount?: number;
715
+ filePreview?: Array<{ path: string; reasons: string[]; hitLines: number[]; snippetCount: number }>;
716
+ };
717
+ if (boundedFiles.externalized) {
718
+ data.files = [];
719
+ data.filesResult = boundedFiles.value;
720
+ data.filesTruncated = true;
721
+ data.fileCount = pack.files.length;
722
+ data.filePreview = pack.files.slice(0, 10).map((file) => ({
723
+ path: file.path,
724
+ reasons: file.reasons.slice(0, 4),
725
+ hitLines: file.hitLines.slice(0, 12),
726
+ snippetCount: file.snippetCount,
727
+ }));
728
+ } else {
729
+ data.files = pack.files;
730
+ }
731
+ if (cognitionAudit) {
732
+ (facade.data as typeof facade.data & { cognitionAudit: typeof cognitionAudit }).cognitionAudit = cognitionAudit;
733
+ }
734
+ return result(facade as unknown as Record<string, unknown>);
735
+ }
736
+ const startedAt = performance.now();
737
+ const requestedCapabilityId = typeof args.capability_id === 'string' ? args.capability_id.trim() : '';
738
+ if (requestedCapabilityId) {
739
+ const pluginMatch = /^plugin\.([^.]+)\.(.+)$/.exec(requestedCapabilityId);
740
+ const manifests = pluginMatch ? (() => {
741
+ const pluginId = pluginMatch[1];
742
+ try {
743
+ return [getAssistantPluginManifest(ctx.controllerHome, repository, pluginId)];
744
+ } catch (error) {
745
+ if (!(error instanceof Error) || !error.message.startsWith('PLUGIN_NOT_FOUND:')) throw error;
746
+ }
747
+ try {
748
+ return [getControllerPluginManifest(ctx.controllerHome, pluginId)];
749
+ } catch (error) {
750
+ if (!(error instanceof Error) || !error.message.startsWith('PLUGIN_NOT_FOUND:')) throw error;
751
+ }
752
+ return [];
753
+ })() : [];
754
+ const descriptor = getCapabilityDescriptor(requestedCapabilityId, manifests);
755
+ const coreCapability = getCoreCapabilityExecutionSchema(requestedCapabilityId);
756
+ const pluginAction = getPluginActionCapabilitySchema(requestedCapabilityId, manifests);
757
+ const facade = buildFacadeResult({
758
+ status: 'ok',
759
+ summary: descriptor
760
+ ? `Exact capability ${requestedCapabilityId} is available.`
761
+ : `Capability ${requestedCapabilityId} was not found.`,
762
+ data: {
763
+ operation,
764
+ repoId: repository.repoId,
765
+ repository: {
766
+ repoId: repository.repoId,
767
+ displayName: repository.displayName,
768
+ defaultBranch: repository.defaultBranch,
769
+ repositoryType: repository.repositoryType,
770
+ },
771
+ capabilityLookup: {
772
+ requestedCapabilityId,
773
+ found: Boolean(descriptor),
774
+ descriptor,
775
+ coreCapability,
776
+ pluginAction,
777
+ },
778
+ toolArchitecture: {
779
+ facadeTools: [...FACADE_TOOLS],
780
+ domainSchemaLoading: 'exact_capability_fast_path',
781
+ },
782
+ bounded: true,
783
+ },
784
+ warnings: [],
785
+ suggestedNextActions: [],
786
+ detailLevel: args.detail_level === 'detail' || args.detail_level === 'raw' ? args.detail_level : 'summary',
787
+ rawAvailable: false,
788
+ });
789
+ const payload = facade as unknown as Record<string, unknown>;
790
+ payload.responseMeta = {
791
+ serverDurationMs: Number((performance.now() - startedAt).toFixed(2)),
792
+ structuredPayloadBytes: 0,
793
+ };
794
+ (payload.responseMeta as { structuredPayloadBytes: number }).structuredPayloadBytes = Buffer.byteLength(JSON.stringify(payload), 'utf8');
795
+ return result(payload);
796
+ }
797
+ const capabilityIntentQuery = operation === 'list' && typeof args.query === 'string'
798
+ ? args.query.trim()
799
+ : '';
800
+ if (capabilityIntentQuery) {
801
+ const learningRecall = args.include_learning_recall === false
802
+ ? undefined
803
+ : rhContextLearningRecall(ctx, repository, capabilityIntentQuery);
804
+ const manifestOptions = { preferStored: true };
805
+ const repositoryManifests = listAssistantPluginManifests(ctx.controllerHome, repository, manifestOptions);
806
+ const controllerManifests = listControllerPluginManifests(ctx.controllerHome, manifestOptions);
807
+ const manifests = [...new Map(
808
+ [...repositoryManifests, ...controllerManifests].map((manifest) => [manifest.pluginId, manifest] as const),
809
+ ).values()];
810
+ const matches = searchCapabilityDescriptors(capabilityIntentQuery, manifests, 12)
811
+ .map((match) => ({
812
+ ...match,
813
+ coreCapability: getCoreCapabilityExecutionSchema(match.capabilityId),
814
+ pluginAction: getPluginActionCapabilitySchema(match.capabilityId, manifests),
815
+ }));
816
+ const facade = buildFacadeResult({
817
+ status: 'ok',
818
+ summary: matches.length > 0
819
+ ? `Found ${matches.length} capability candidate(s) for intent: ${capabilityIntentQuery}`
820
+ : `No capability candidates matched intent: ${capabilityIntentQuery}`,
821
+ data: {
822
+ operation,
823
+ repoId: repository.repoId,
824
+ capabilitySearch: {
825
+ query: capabilityIntentQuery,
826
+ matches,
827
+ readOnlyDiscovery: true,
828
+ executeWith: 'capability-specific',
829
+ },
830
+ ...(learningRecall ? { learningRecall } : {}),
831
+ toolArchitecture: {
832
+ facadeTools: [...FACADE_TOOLS],
833
+ domainSchemaLoading: 'intent_ranked_capability_search',
834
+ exactCapabilityLookupStillAvailable: true,
835
+ },
836
+ bounded: true,
837
+ },
838
+ warnings: [],
839
+ suggestedNextActions: [],
840
+ detailLevel: args.detail_level === 'detail' || args.detail_level === 'raw' ? args.detail_level : 'summary',
841
+ rawAvailable: false,
842
+ });
843
+ return result(facade as unknown as Record<string, unknown>);
844
+ }
845
+ const requested = Array.isArray(args.requested_check_ids) ? args.requested_check_ids.map(String) : [];
846
+ const detailLevel = args.detail_level === 'detail' || args.detail_level === 'raw' ? args.detail_level : 'summary';
847
+ const isSummary = detailLevel === 'summary';
848
+ const checks = requested.length > 0 || !isSummary ? listControllerChecks(repository.canonicalRoot) : [];
849
+ const normalizedChecks = normalizeCheckIds(requested, checks);
850
+ const store = { controllerHome: ctx.controllerHome, repoId: repository.repoId };
851
+ const workId = typeof args.work_id === 'string' ? args.work_id : undefined;
852
+ const work = workId ? getWorkContract(store, workId) : undefined;
853
+ const executionJob = workId && !work ? (() => { try { return getExecutionJob(ctx.controllerHome, repository.repoId, workId); } catch { return undefined; } })() : undefined;
854
+ if (workId && !work && !executionJob) {
855
+ const facade = buildFacadeResult({
856
+ status: 'not_found',
857
+ summary: `Work ${workId} not found in this repository.`,
858
+ data: { operation, repoId: repository.repoId, workId },
859
+ suggestedNextActions: [],
860
+ });
861
+ return result(facade as unknown as Record<string, unknown>, true);
862
+ }
863
+ const activeWorkProjection = operation === 'list' || !workId
864
+ ? readActiveWorkCandidates({ ...store, limit: 20 })
865
+ : { contracts: [], invalid: [] as InvalidActiveWorkCandidate[] };
866
+ const activeContractScan = activeWorkProjection.contracts;
867
+ const currentLineageWorkIds = work
868
+ ? currentTaskLineageWorkIds([work.workId], readWorkContractStore(store).contracts)
869
+ : new Set<string>();
870
+ const recentActivityCutoffMs = Date.now() - RH_CONTEXT_RECENT_ACTIVITY_WINDOW_MS;
871
+ const recentActiveContractScan = isSummary
872
+ ? activeContractScan.filter((contract) => isRecentRhContextWork(contract, recentActivityCutoffMs))
873
+ : activeContractScan;
874
+ const activeContracts = isSummary ? recentActiveContractScan.slice(0, 3) : activeContractScan;
875
+ const recentJobs = !isSummary && (operation === 'list' || !workId)
876
+ ? listExecutionJobs(ctx.controllerHome, repository.repoId, 20)
877
+ .filter((job) => timestampIsRecent(job.updatedAt, recentActivityCutoffMs))
878
+ .slice(0, 5)
879
+ : [];
880
+ const processScan = isSummary
881
+ ? listRecoverableProcessRecords(ctx.controllerHome, repository.repoId)
882
+ : listProcessRecords(ctx.controllerHome, repository.repoId, workId ? 100 : 50);
883
+ const relevantProcesses = processScan.filter((process) => work
884
+ ? Boolean(process.workId && currentLineageWorkIds.has(process.workId))
885
+ : timestampIsRecent(process.updatedAt, recentActivityCutoffMs));
886
+ const liveProcessIds = new Set(processRuntimeResourceDiagnostics().activeProcessIds);
887
+ const activeProcesses = relevantProcesses.filter((process) => liveProcessIds.has(process.processId) && isManagedProcessActive(process));
888
+ const workController = work ? getControllerSession(store, work.workId) : undefined;
889
+ const manifestOptions = { preferStored: true };
890
+ const manifests = isSummary
891
+ ? []
892
+ : (() => {
893
+ const repositoryManifests = listAssistantPluginManifests(ctx.controllerHome, repository, manifestOptions);
894
+ const controllerManifests = listControllerPluginManifests(ctx.controllerHome, manifestOptions);
895
+ return [...new Map(
896
+ [...repositoryManifests, ...controllerManifests].map((manifest) => [manifest.pluginId, manifest] as const),
897
+ ).values()];
898
+ })();
899
+ const capabilities = isSummary ? [] : listCapabilityDescriptors(manifests);
900
+ const capabilityGroups = isSummary ? [] : summarizeCapabilityGroups(manifests);
901
+ const capabilityLookup = undefined;
902
+ const selectedChecks = normalizedChecks.validCheckIds
903
+ .map((id) => checks.find((check) => check.id === id))
904
+ .filter((check): check is (typeof checks)[number] => Boolean(check))
905
+ .map((check) => ({ id: check.id, description: check.description, source: check.source }));
906
+ const pendingAttention = listHandoffItems({ ...store, status: 'pending', limit: isSummary ? 20 : 5 });
907
+ const currentAttentionScan = listHandoffAttentionItems(store, isSummary ? 20 : 5);
908
+ const workAttentionItems = work
909
+ ? currentAttentionScan.filter((item) => Boolean(item.workId && currentLineageWorkIds.has(item.workId)))
910
+ : [];
911
+ const workAttention = workAttentionItems[0];
912
+ const resumeContext = work ? (() => {
913
+ const semanticWork = workSemanticView(work);
914
+ const requirementRecord = work.requirementId?.trim()
915
+ ? readRequirement({ controllerHome: ctx.controllerHome }, work.requirementId.trim())
916
+ : undefined;
917
+ const semanticRequirement = requirementRecord ? requirementSemanticView(requirementRecord.value) : undefined;
918
+ const plan = work.planId?.trim() ? getPlanContract(store, work.planId.trim()) : undefined;
919
+ const semanticPlan = plan ? planSemanticView(plan) : undefined;
920
+ const exactCheckout = work.checkoutId?.trim()
921
+ ? repository.checkouts.find((candidate) => candidate.checkoutId === work.checkoutId)
922
+ : repository.checkouts.find((candidate) => candidate.checkoutId === repository.activeCheckoutId);
923
+ const source = freshGitIdentity(exactCheckout?.canonicalRoot ?? repository.canonicalRoot);
924
+ const unresolvedHumanRequests = workAttentionItems
925
+ .filter((item) => Boolean(item.creationReason && RESUME_CONTEXT_HUMAN_REQUEST_REASONS.has(item.creationReason)))
926
+ .slice(0, 8)
927
+ .map((item) => ({
928
+ id: item.id,
929
+ reason: item.reason.slice(0, 500),
930
+ creationReason: item.creationReason,
931
+ blockingDecision: item.blockingDecision?.slice(0, 500),
932
+ recommendedDecision: item.recommendedDecision.slice(0, 500),
933
+ }));
934
+ const checkReceiptRefs = work.checkRefs
935
+ .flatMap((record) => record.receipt?.receiptId?.trim() ? [record.receipt.receiptId.trim()] : [])
936
+ .slice(-24);
937
+ return {
938
+ schemaVersion: 1 as const,
939
+ derived: true as const,
940
+ semantic: {
941
+ ...(semanticRequirement ? { requirement: semanticRequirement } : {}),
942
+ ...(semanticPlan ? { plan: semanticPlan } : {}),
943
+ work: semanticWork,
944
+ },
945
+ source: {
946
+ checkoutId: exactCheckout?.checkoutId ?? work.checkoutId,
947
+ worktree: exactCheckout?.worktree ?? false,
948
+ head: source.head,
949
+ branch: source.branch,
950
+ dirty: source.dirty,
951
+ workingTreeFingerprint: source.workingTreeFingerprint,
952
+ observedAt: new Date(source.sampledAt).toISOString(),
953
+ },
954
+ staleness: {
955
+ requirementBasisStale: Boolean(semanticRequirement && semanticPlan?.requirementBasisRevision && semanticRequirement.revision !== semanticPlan.requirementBasisRevision),
956
+ workRequirementBasisStale: Boolean(semanticRequirement && semanticWork.requirementRevision && semanticRequirement.revision !== semanticWork.requirementRevision),
957
+ workPlanBasisStale: Boolean(semanticPlan && semanticWork.planRevision && semanticPlan.revision !== semanticWork.planRevision),
958
+ sourceBasisStale: Boolean(semanticPlan?.sourceBasisRevision && source.head && semanticPlan.sourceBasisRevision !== source.head),
959
+ advisoryOnly: true as const,
960
+ },
961
+ unresolvedHumanRequests,
962
+ durableHandles: {
963
+ processes: relevantProcesses.slice(0, 8).map((process) => ({
964
+ processId: process.processId,
965
+ status: process.status,
966
+ workId: process.workId,
967
+ updatedAt: process.updatedAt,
968
+ })),
969
+ ...(workController ? { controller: {
970
+ controllerType: workController.controllerType,
971
+ sessionId: workController.sessionId,
972
+ leaseExpiresAt: workController.leaseExpiresAt,
973
+ } } : {}),
974
+ },
975
+ receipts: {
976
+ resultRefs: semanticWork.resultRefs,
977
+ ...(work.completionReceipt?.receiptId?.trim() ? { completionReceiptRef: work.completionReceipt.receiptId.trim() } : {}),
978
+ checkReceiptRefs,
979
+ },
980
+ };
981
+ })() : undefined;
982
+ const currentAttentionItems = work
983
+ ? workAttentionItems
984
+ : isSummary
985
+ ? currentAttentionScan.slice(0, 3)
986
+ : currentAttentionScan;
987
+ const attention = isSummary
988
+ ? currentAttentionItems.map((item) => ({
989
+ id: item.id,
990
+ workId: item.workId,
991
+ title: item.title.slice(0, 96),
992
+ severity: item.severity,
993
+ reason: item.reason.slice(0, 160),
994
+ blockingDecision: item.blockingDecision?.slice(0, 160),
995
+ updatedAt: item.updatedAt,
996
+ }))
997
+ : currentAttentionItems.map(summarizeHandoffItem);
998
+ const detailCheckCandidates = requested.length > 0
999
+ ? selectedChecks
1000
+ : checks.map((check) => ({ id: check.id, description: check.description, source: check.source }));
1001
+ const checkSummaries = isSummary ? selectedChecks : detailCheckCandidates.slice(0, 24);
1002
+ const detailArguments = {
1003
+ repo_id: repository.repoId,
1004
+ operation,
1005
+ ...(workId ? { work_id: workId } : {}),
1006
+ ...(requested.length ? { requested_check_ids: requested } : {}),
1007
+ };
1008
+ const summaryData = {
1009
+ operation,
1010
+ repoId: repository.repoId,
1011
+ repository: {
1012
+ repoId: repository.repoId,
1013
+ displayName: repository.displayName,
1014
+ defaultBranch: repository.defaultBranch,
1015
+ repositoryType: repository.repositoryType,
1016
+ },
1017
+ checks: selectedChecks,
1018
+ selectedChecks,
1019
+ requestedCheckIds: requested,
1020
+ normalizedChecks,
1021
+ invalidCheckIdsAreNotFailures: true,
1022
+ capabilityInventory: {
1023
+ mode: 'detail_only',
1024
+ deferred: true,
1025
+ reason: 'Work/repository summary does not hydrate plugin manifests; request capability_id or detail/raw only when schema/policy detail is needed.',
1026
+ },
1027
+ capabilityLookup,
1028
+ toolArchitecture: {
1029
+ facadeTools: ['rh_access', 'rh_status', 'rh_inbox', 'rh_context', 'rh_work'],
1030
+ domainSchemaLoading: 'static_stable_surface',
1031
+ },
1032
+ work: work
1033
+ ? {
1034
+ workId: work.workId,
1035
+ state: work.semanticState,
1036
+ objective: work.objective.slice(0, 160),
1037
+ continuation: buildWorkContinuationSnapshot(work),
1038
+ }
1039
+ : undefined,
1040
+ executionJob: executionJob ? summarizeWorkListItem(executionJob) : undefined,
1041
+ executionState: work ? (workAttention ? 'blocked' : activeProcesses.length > 0 ? 'executing' : workController ? 'controller_active' : 'waiting_trigger') : undefined,
1042
+ activeController: workController ? { controllerType: workController.controllerType, sessionId: workController.sessionId, leaseExpiresAt: workController.leaseExpiresAt } : undefined,
1043
+ activeProcesses: activeProcesses.slice(0, 3).map((process) => ({ processId: process.processId, workId: process.workId, status: process.status, route: process.route, startedAt: process.startedAt, updatedAt: process.updatedAt })),
1044
+ recentProcesses: relevantProcesses.slice(0, 5).map((process) => ({ processId: process.processId, workId: process.workId, status: process.status, route: process.route, startedAt: process.startedAt, updatedAt: process.updatedAt })),
1045
+ currentTask: work ? currentTaskSemanticProjectionForWork(work) : undefined,
1046
+ ...(resumeContext ? { resumeContext } : {}),
1047
+ activeWork: activeContracts.map((entry) => ({
1048
+ relation: 'repository_inventory' as const,
1049
+ relevance: ['ownership', 'conflict', 'release_admission'] as const,
1050
+ workId: entry.workId,
1051
+ state: entry.semanticState,
1052
+ })),
1053
+ invalidActiveWork: activeWorkProjection.invalid.slice(0, 3).map(summarizeInvalidActiveWorkCandidate),
1054
+ activeAttention: attention,
1055
+ counts: {
1056
+ availableChecks: checks.length,
1057
+ selectedChecks: selectedChecks.length,
1058
+ capabilityInventoryDeferred: true,
1059
+ activeWork: recentActiveContractScan.length,
1060
+ activeWorkShown: activeContracts.length,
1061
+ recentActiveWork: recentActiveContractScan.length,
1062
+ invalidActiveWork: activeWorkProjection.invalid.length,
1063
+ invalidActiveWorkShown: Math.min(activeWorkProjection.invalid.length, 3),
1064
+ storedNonTerminalWork: activeContractScan.length,
1065
+ currentWork: work ? 1 : 0,
1066
+ historicalNonTerminalWork: Math.max(0, activeContractScan.length - recentActiveContractScan.length),
1067
+ currentAttention: work ? workAttentionItems.length : 0,
1068
+ repositoryAttention: currentAttentionScan.length,
1069
+ currentAttentionShown: attention.length,
1070
+ activeProcesses: activeProcesses.length,
1071
+ recentProcesses: relevantProcesses.length,
1072
+ historicalProcessScanDeferred: true,
1073
+ pendingAttentionScanned: pendingAttention.length,
1074
+ historicalPendingAttention: Math.max(0, pendingAttention.length - currentAttentionScan.length),
1075
+ omittedCurrentAttention: Math.max(0, (work ? workAttentionItems.length : 0) - attention.length),
1076
+ omittedPendingAttention: Math.max(0, pendingAttention.length - attention.length),
1077
+ },
1078
+ historicalExecutionJobsIncluded: false,
1079
+ detailPointers: {
1080
+ detail: { tool: 'rh_context', arguments: { ...detailArguments, detail_level: 'detail' } },
1081
+ raw: { tool: 'rh_context', arguments: { ...detailArguments, detail_level: 'raw' } },
1082
+ },
1083
+ bounded: true,
1084
+ };
1085
+ const detailCapabilities = capabilities.slice(0, 24);
1086
+ const detailData = {
1087
+ operation,
1088
+ repoId: repository.repoId,
1089
+ repository: repositorySummary(repository),
1090
+ checks: checkSummaries,
1091
+ omittedCheckCount: Math.max(0, checks.length - checkSummaries.length),
1092
+ selectedChecks,
1093
+ requestedCheckIds: requested,
1094
+ normalizedChecks,
1095
+ invalidCheckIdsAreNotFailures: true,
1096
+ capabilityCount: capabilities.length,
1097
+ capabilities: detailCapabilities,
1098
+ omittedCapabilityCount: Math.max(0, capabilities.length - detailCapabilities.length),
1099
+ capabilityGroups,
1100
+ capabilityLookup,
1101
+ toolArchitecture: {
1102
+ facadeTools: ['rh_access', 'rh_status', 'rh_inbox', 'rh_context', 'rh_work'],
1103
+ atomicTypedToolsRetained: true,
1104
+ internalHandlersRetained: true,
1105
+ domainSchemaLoading: 'static_stable_surface',
1106
+ dynamicDomainSchemaLoadingSupported: false,
1107
+ },
1108
+ currentTask: work ? currentTaskSemanticProjectionForWork(work) : undefined,
1109
+ ...(resumeContext ? { resumeContext } : {}),
1110
+ work: work ? { ...work, continuation: buildWorkContinuationSnapshot(work) } : undefined,
1111
+ executionJob: executionJob ? summarizeWorkListItem(executionJob) : undefined,
1112
+ executionState: work ? (workAttention ? 'blocked' : activeProcesses.length > 0 ? 'executing' : workController ? 'controller_active' : 'waiting_trigger') : undefined,
1113
+ activeController: workController,
1114
+ activeProcesses: activeProcesses.slice(0, 10),
1115
+ recentProcesses: relevantProcesses.slice(0, 20),
1116
+ activeWork: activeContracts.map((entry) => ({
1117
+ relation: 'repository_inventory' as const,
1118
+ relevance: ['ownership', 'conflict', 'release_admission'] as const,
1119
+ workId: entry.workId,
1120
+ state: entry.semanticState,
1121
+ })),
1122
+ invalidActiveWork: activeWorkProjection.invalid.slice(0, 10).map(summarizeInvalidActiveWorkCandidate),
1123
+ recentExecutionJobs: recentJobs.map(summarizeWorkListItem),
1124
+ activeAttention: attention,
1125
+ counts: {
1126
+ availableChecks: checks.length,
1127
+ selectedChecks: selectedChecks.length,
1128
+ capabilities: capabilities.length,
1129
+ activeWork: activeContracts.length,
1130
+ invalidActiveWork: activeWorkProjection.invalid.length,
1131
+ recentExecutionJobs: recentJobs.length,
1132
+ activeProcesses: activeProcesses.length,
1133
+ recentProcesses: relevantProcesses.length,
1134
+ activeAttention: attention.length,
1135
+ },
1136
+ bounded: true,
1137
+ };
1138
+ const facade = buildFacadeResult({
1139
+ status: 'ok',
1140
+ summary: work
1141
+ ? `Bounded context for work ${work.workId}.`
1142
+ : executionJob
1143
+ ? `Bounded context for execution job ${executionJob.jobId}.`
1144
+ : 'Bounded repository context and active work summaries are available.',
1145
+ data: isSummary ? summaryData : detailData,
1146
+ warnings: normalizedChecks.warnings,
1147
+ evidenceRefs: work?.evidenceRefs?.slice(0, 5) ?? [],
1148
+ suggestedNextActions: normalizedChecks.suggestedNextActions.length ? normalizedChecks.suggestedNextActions : [{
1149
+ label: 'Choose work mode',
1150
+ tool: 'rh_work',
1151
+ operation: 'start',
1152
+ risk: 'workspace_write',
1153
+ confidence: 'medium',
1154
+ }],
1155
+ detailLevel,
1156
+ rawAvailable: detailLevel === 'raw',
1157
+ });
1158
+ const payload = facade as unknown as Record<string, unknown>;
1159
+ if (isSummary) {
1160
+ payload.responseMeta = {
1161
+ serverDurationMs: Number((performance.now() - startedAt).toFixed(2)),
1162
+ structuredPayloadBytes: 0,
1163
+ };
1164
+ (payload.responseMeta as { structuredPayloadBytes: number }).structuredPayloadBytes = Buffer.byteLength(JSON.stringify(payload), 'utf8');
1165
+ }
1166
+ return result(payload);
1167
+ }