@caupulican/pi-adaptative 0.81.39 → 0.81.40

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 (667) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +2 -0
  3. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts +2 -0
  4. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts.map +1 -1
  5. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js +2 -0
  6. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js.map +1 -1
  7. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.ts +3 -0
  8. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts +9 -0
  9. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts.map +1 -1
  10. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js +290 -107
  11. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js.map +1 -1
  12. package/dist/bundled-resources/extensions/tmux-agent-manager/index.ts +357 -122
  13. package/dist/bundled-resources/skills/tool-call-repair/references/repair-catalogue.md +2 -2
  14. package/dist/cli/args.d.ts +2 -0
  15. package/dist/cli/args.d.ts.map +1 -1
  16. package/dist/cli/args.js +9 -0
  17. package/dist/cli/args.js.map +1 -1
  18. package/dist/core/agent-directory-layout.d.ts +15 -0
  19. package/dist/core/agent-directory-layout.d.ts.map +1 -0
  20. package/dist/core/agent-directory-layout.js +72 -0
  21. package/dist/core/agent-directory-layout.js.map +1 -0
  22. package/dist/core/agent-paths.d.ts +19 -2
  23. package/dist/core/agent-paths.d.ts.map +1 -1
  24. package/dist/core/agent-paths.js +67 -4
  25. package/dist/core/agent-paths.js.map +1 -1
  26. package/dist/core/agent-session-runtime.d.ts +52 -8
  27. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  28. package/dist/core/agent-session-runtime.js +397 -79
  29. package/dist/core/agent-session-runtime.js.map +1 -1
  30. package/dist/core/agent-session-services.d.ts +1 -0
  31. package/dist/core/agent-session-services.d.ts.map +1 -1
  32. package/dist/core/agent-session-services.js +1 -0
  33. package/dist/core/agent-session-services.js.map +1 -1
  34. package/dist/core/agent-session.d.ts +71 -136
  35. package/dist/core/agent-session.d.ts.map +1 -1
  36. package/dist/core/agent-session.js +477 -1318
  37. package/dist/core/agent-session.js.map +1 -1
  38. package/dist/core/autonomy/approval-gate.d.ts +3 -2
  39. package/dist/core/autonomy/approval-gate.d.ts.map +1 -1
  40. package/dist/core/autonomy/approval-gate.js +6 -28
  41. package/dist/core/autonomy/approval-gate.js.map +1 -1
  42. package/dist/core/autonomy/bounded-completion.d.ts +1 -1
  43. package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
  44. package/dist/core/autonomy/bounded-completion.js +1 -1
  45. package/dist/core/autonomy/bounded-completion.js.map +1 -1
  46. package/dist/core/autonomy/contracts.d.ts +20 -12
  47. package/dist/core/autonomy/contracts.d.ts.map +1 -1
  48. package/dist/core/autonomy/contracts.js.map +1 -1
  49. package/dist/core/autonomy/foreground-envelope.d.ts +8 -2
  50. package/dist/core/autonomy/foreground-envelope.d.ts.map +1 -1
  51. package/dist/core/autonomy/foreground-envelope.js +8 -25
  52. package/dist/core/autonomy/foreground-envelope.js.map +1 -1
  53. package/dist/core/autonomy/gates.d.ts.map +1 -1
  54. package/dist/core/autonomy/gates.js +8 -10
  55. package/dist/core/autonomy/gates.js.map +1 -1
  56. package/dist/core/autonomy/lane-private-paths.d.ts +2 -0
  57. package/dist/core/autonomy/lane-private-paths.d.ts.map +1 -0
  58. package/dist/core/autonomy/lane-private-paths.js +16 -0
  59. package/dist/core/autonomy/lane-private-paths.js.map +1 -0
  60. package/dist/core/autonomy/lane-tool-surface.d.ts +10 -0
  61. package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
  62. package/dist/core/autonomy/lane-tool-surface.js +46 -8
  63. package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
  64. package/dist/core/autonomy/lane-tracker.d.ts +14 -0
  65. package/dist/core/autonomy/lane-tracker.d.ts.map +1 -1
  66. package/dist/core/autonomy/lane-tracker.js +38 -0
  67. package/dist/core/autonomy/lane-tracker.js.map +1 -1
  68. package/dist/core/autonomy/risk-assessment.d.ts +1 -2
  69. package/dist/core/autonomy/risk-assessment.d.ts.map +1 -1
  70. package/dist/core/autonomy/risk-assessment.js +1 -123
  71. package/dist/core/autonomy/risk-assessment.js.map +1 -1
  72. package/dist/core/autonomy/session-lane-record.d.ts +4 -4
  73. package/dist/core/autonomy/session-lane-record.d.ts.map +1 -1
  74. package/dist/core/autonomy/session-lane-record.js +16 -29
  75. package/dist/core/autonomy/session-lane-record.js.map +1 -1
  76. package/dist/core/autonomy/telemetry-events.d.ts +1 -1
  77. package/dist/core/autonomy/telemetry-events.d.ts.map +1 -1
  78. package/dist/core/autonomy/telemetry-events.js +1 -1
  79. package/dist/core/autonomy/telemetry-events.js.map +1 -1
  80. package/dist/core/autonomy-telemetry.d.ts +7 -7
  81. package/dist/core/autonomy-telemetry.d.ts.map +1 -1
  82. package/dist/core/autonomy-telemetry.js +9 -9
  83. package/dist/core/autonomy-telemetry.js.map +1 -1
  84. package/dist/core/background-lane-controller.d.ts +54 -236
  85. package/dist/core/background-lane-controller.d.ts.map +1 -1
  86. package/dist/core/background-lane-controller.js +140 -1273
  87. package/dist/core/background-lane-controller.js.map +1 -1
  88. package/dist/core/capability-contract.d.ts +4 -0
  89. package/dist/core/capability-contract.d.ts.map +1 -0
  90. package/dist/core/capability-contract.js +28 -0
  91. package/dist/core/capability-contract.js.map +1 -0
  92. package/dist/core/compaction-controller.d.ts +90 -0
  93. package/dist/core/compaction-controller.d.ts.map +1 -0
  94. package/dist/core/compaction-controller.js +452 -0
  95. package/dist/core/compaction-controller.js.map +1 -0
  96. package/dist/core/compaction-support.d.ts +12 -11
  97. package/dist/core/compaction-support.d.ts.map +1 -1
  98. package/dist/core/compaction-support.js.map +1 -1
  99. package/dist/core/context/context-artifacts.d.ts +6 -2
  100. package/dist/core/context/context-artifacts.d.ts.map +1 -1
  101. package/dist/core/context/context-artifacts.js +34 -2
  102. package/dist/core/context/context-artifacts.js.map +1 -1
  103. package/dist/core/context/context-store-retention.d.ts +8 -2
  104. package/dist/core/context/context-store-retention.d.ts.map +1 -1
  105. package/dist/core/context/context-store-retention.js +158 -35
  106. package/dist/core/context/context-store-retention.js.map +1 -1
  107. package/dist/core/context/okf-memory.d.ts.map +1 -1
  108. package/dist/core/context/okf-memory.js +9 -11
  109. package/dist/core/context/okf-memory.js.map +1 -1
  110. package/dist/core/context/sqlite-runtime-index.d.ts.map +1 -1
  111. package/dist/core/context/sqlite-runtime-index.js +6 -8
  112. package/dist/core/context/sqlite-runtime-index.js.map +1 -1
  113. package/dist/core/context-gc.d.ts +3 -0
  114. package/dist/core/context-gc.d.ts.map +1 -1
  115. package/dist/core/context-gc.js +10 -5
  116. package/dist/core/context-gc.js.map +1 -1
  117. package/dist/core/context-pipeline.d.ts.map +1 -1
  118. package/dist/core/context-pipeline.js +9 -4
  119. package/dist/core/context-pipeline.js.map +1 -1
  120. package/dist/core/default-tool-surface.d.ts.map +1 -1
  121. package/dist/core/default-tool-surface.js +1 -0
  122. package/dist/core/default-tool-surface.js.map +1 -1
  123. package/dist/core/delegation/managed-lane-controller.d.ts +34 -0
  124. package/dist/core/delegation/managed-lane-controller.d.ts.map +1 -0
  125. package/dist/core/delegation/managed-lane-controller.js +217 -0
  126. package/dist/core/delegation/managed-lane-controller.js.map +1 -0
  127. package/dist/core/delegation/session-worker-claim.d.ts +44 -0
  128. package/dist/core/delegation/session-worker-claim.d.ts.map +1 -0
  129. package/dist/core/delegation/session-worker-claim.js +98 -0
  130. package/dist/core/delegation/session-worker-claim.js.map +1 -0
  131. package/dist/core/delegation/worker-actions.d.ts +7 -5
  132. package/dist/core/delegation/worker-actions.d.ts.map +1 -1
  133. package/dist/core/delegation/worker-actions.js +20 -4
  134. package/dist/core/delegation/worker-actions.js.map +1 -1
  135. package/dist/core/delegation/{worker-result.d.ts → worker-claim.d.ts} +13 -13
  136. package/dist/core/delegation/worker-claim.d.ts.map +1 -0
  137. package/dist/core/delegation/{worker-result.js → worker-claim.js} +61 -51
  138. package/dist/core/delegation/worker-claim.js.map +1 -0
  139. package/dist/core/delegation/worker-delegation-controller.d.ts +110 -0
  140. package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -0
  141. package/dist/core/delegation/worker-delegation-controller.js +861 -0
  142. package/dist/core/delegation/worker-delegation-controller.js.map +1 -0
  143. package/dist/core/delegation/worker-delegation-request.d.ts +11 -0
  144. package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -0
  145. package/dist/core/delegation/worker-delegation-request.js +2 -0
  146. package/dist/core/delegation/worker-delegation-request.js.map +1 -0
  147. package/dist/core/delegation/worker-dispatch-scheduler.d.ts +40 -0
  148. package/dist/core/delegation/worker-dispatch-scheduler.d.ts.map +1 -0
  149. package/dist/core/delegation/worker-dispatch-scheduler.js +93 -0
  150. package/dist/core/delegation/worker-dispatch-scheduler.js.map +1 -0
  151. package/dist/core/delegation/worker-execution-policy.d.ts +62 -0
  152. package/dist/core/delegation/worker-execution-policy.d.ts.map +1 -0
  153. package/dist/core/delegation/worker-execution-policy.js +160 -0
  154. package/dist/core/delegation/worker-execution-policy.js.map +1 -0
  155. package/dist/core/delegation/worker-lane-projection.d.ts +14 -0
  156. package/dist/core/delegation/worker-lane-projection.d.ts.map +1 -0
  157. package/dist/core/delegation/worker-lane-projection.js +100 -0
  158. package/dist/core/delegation/worker-lane-projection.js.map +1 -0
  159. package/dist/core/delegation/worker-lifecycle.d.ts +97 -0
  160. package/dist/core/delegation/worker-lifecycle.d.ts.map +1 -0
  161. package/dist/core/delegation/worker-lifecycle.js +339 -0
  162. package/dist/core/delegation/worker-lifecycle.js.map +1 -0
  163. package/dist/core/delegation/worker-notification-coordinator.d.ts +36 -0
  164. package/dist/core/delegation/worker-notification-coordinator.d.ts.map +1 -0
  165. package/dist/core/delegation/worker-notification-coordinator.js +90 -0
  166. package/dist/core/delegation/worker-notification-coordinator.js.map +1 -0
  167. package/dist/core/delegation/worker-profile-resolver.d.ts +55 -0
  168. package/dist/core/delegation/worker-profile-resolver.d.ts.map +1 -0
  169. package/dist/core/delegation/worker-profile-resolver.js +113 -0
  170. package/dist/core/delegation/worker-profile-resolver.js.map +1 -0
  171. package/dist/core/delegation/worker-runner.d.ts +25 -14
  172. package/dist/core/delegation/worker-runner.d.ts.map +1 -1
  173. package/dist/core/delegation/worker-runner.js +122 -53
  174. package/dist/core/delegation/worker-runner.js.map +1 -1
  175. package/dist/core/delegation/worker-task-label.d.ts +3 -0
  176. package/dist/core/delegation/worker-task-label.d.ts.map +1 -0
  177. package/dist/core/delegation/worker-task-label.js +11 -0
  178. package/dist/core/delegation/worker-task-label.js.map +1 -0
  179. package/dist/core/doctor.d.ts +8 -0
  180. package/dist/core/doctor.d.ts.map +1 -1
  181. package/dist/core/doctor.js +32 -1
  182. package/dist/core/doctor.js.map +1 -1
  183. package/dist/core/extensions/index.d.ts +1 -1
  184. package/dist/core/extensions/index.d.ts.map +1 -1
  185. package/dist/core/extensions/index.js.map +1 -1
  186. package/dist/core/extensions/loader.d.ts +5 -1
  187. package/dist/core/extensions/loader.d.ts.map +1 -1
  188. package/dist/core/extensions/loader.js +50 -15
  189. package/dist/core/extensions/loader.js.map +1 -1
  190. package/dist/core/extensions/runner.d.ts.map +1 -1
  191. package/dist/core/extensions/runner.js +6 -0
  192. package/dist/core/extensions/runner.js.map +1 -1
  193. package/dist/core/extensions/storage.d.ts +8 -0
  194. package/dist/core/extensions/storage.d.ts.map +1 -0
  195. package/dist/core/extensions/storage.js +28 -0
  196. package/dist/core/extensions/storage.js.map +1 -0
  197. package/dist/core/extensions/types.d.ts +70 -21
  198. package/dist/core/extensions/types.d.ts.map +1 -1
  199. package/dist/core/extensions/types.js.map +1 -1
  200. package/dist/core/failure-corpus.d.ts +1 -15
  201. package/dist/core/failure-corpus.d.ts.map +1 -1
  202. package/dist/core/failure-corpus.js +9 -37
  203. package/dist/core/failure-corpus.js.map +1 -1
  204. package/dist/core/foreground-recovery-controller.d.ts +52 -0
  205. package/dist/core/foreground-recovery-controller.d.ts.map +1 -0
  206. package/dist/core/foreground-recovery-controller.js +111 -0
  207. package/dist/core/foreground-recovery-controller.js.map +1 -0
  208. package/dist/core/gateways/channel-provider.d.ts +3 -0
  209. package/dist/core/gateways/channel-provider.d.ts.map +1 -1
  210. package/dist/core/gateways/channel-provider.js +31 -6
  211. package/dist/core/gateways/channel-provider.js.map +1 -1
  212. package/dist/core/goals/goal-acceptance.d.ts +11 -0
  213. package/dist/core/goals/goal-acceptance.d.ts.map +1 -0
  214. package/dist/core/goals/goal-acceptance.js +25 -0
  215. package/dist/core/goals/goal-acceptance.js.map +1 -0
  216. package/dist/core/goals/goal-auto-continue-controller.d.ts +27 -0
  217. package/dist/core/goals/goal-auto-continue-controller.d.ts.map +1 -0
  218. package/dist/core/goals/goal-auto-continue-controller.js +93 -0
  219. package/dist/core/goals/goal-auto-continue-controller.js.map +1 -0
  220. package/dist/core/goals/goal-continuation-controller.d.ts +1 -1
  221. package/dist/core/goals/goal-continuation-controller.d.ts.map +1 -1
  222. package/dist/core/goals/goal-continuation-controller.js +10 -0
  223. package/dist/core/goals/goal-continuation-controller.js.map +1 -1
  224. package/dist/core/goals/goal-continuation-prompt.d.ts +1 -1
  225. package/dist/core/goals/goal-continuation-prompt.d.ts.map +1 -1
  226. package/dist/core/goals/goal-continuation-prompt.js +6 -6
  227. package/dist/core/goals/goal-continuation-prompt.js.map +1 -1
  228. package/dist/core/goals/goal-lifecycle.d.ts +20 -0
  229. package/dist/core/goals/goal-lifecycle.d.ts.map +1 -0
  230. package/dist/core/goals/goal-lifecycle.js +17 -0
  231. package/dist/core/goals/goal-lifecycle.js.map +1 -0
  232. package/dist/core/goals/goal-runtime-snapshot.d.ts +11 -9
  233. package/dist/core/goals/goal-runtime-snapshot.d.ts.map +1 -1
  234. package/dist/core/goals/goal-runtime-snapshot.js +10 -8
  235. package/dist/core/goals/goal-runtime-snapshot.js.map +1 -1
  236. package/dist/core/goals/goal-state.d.ts +1 -0
  237. package/dist/core/goals/goal-state.d.ts.map +1 -1
  238. package/dist/core/goals/goal-state.js +7 -10
  239. package/dist/core/goals/goal-state.js.map +1 -1
  240. package/dist/core/goals/goal-tool-core.d.ts +8 -6
  241. package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
  242. package/dist/core/goals/goal-tool-core.js +11 -41
  243. package/dist/core/goals/goal-tool-core.js.map +1 -1
  244. package/dist/core/goals/session-goal-state.d.ts +2 -4
  245. package/dist/core/goals/session-goal-state.d.ts.map +1 -1
  246. package/dist/core/goals/session-goal-state.js +10 -33
  247. package/dist/core/goals/session-goal-state.js.map +1 -1
  248. package/dist/core/human-input.d.ts +100 -0
  249. package/dist/core/human-input.d.ts.map +1 -0
  250. package/dist/core/human-input.js +362 -0
  251. package/dist/core/human-input.js.map +1 -0
  252. package/dist/core/index.d.ts +9 -1
  253. package/dist/core/index.d.ts.map +1 -1
  254. package/dist/core/index.js +9 -1
  255. package/dist/core/index.js.map +1 -1
  256. package/dist/core/{telemetry.d.ts → install-telemetry.d.ts} +1 -1
  257. package/dist/core/install-telemetry.d.ts.map +1 -0
  258. package/dist/core/{telemetry.js → install-telemetry.js} +1 -1
  259. package/dist/core/install-telemetry.js.map +1 -0
  260. package/dist/core/keybindings.d.ts +17 -1
  261. package/dist/core/keybindings.d.ts.map +1 -1
  262. package/dist/core/keybindings.js +24 -6
  263. package/dist/core/keybindings.js.map +1 -1
  264. package/dist/core/learning/learning-audit.d.ts +2 -4
  265. package/dist/core/learning/learning-audit.d.ts.map +1 -1
  266. package/dist/core/learning/learning-audit.js +9 -29
  267. package/dist/core/learning/learning-audit.js.map +1 -1
  268. package/dist/core/learning/learning-gate.d.ts.map +1 -1
  269. package/dist/core/learning/learning-gate.js +1 -6
  270. package/dist/core/learning/learning-gate.js.map +1 -1
  271. package/dist/core/learning/session-learning-decision.d.ts +2 -4
  272. package/dist/core/learning/session-learning-decision.d.ts.map +1 -1
  273. package/dist/core/learning/session-learning-decision.js +9 -29
  274. package/dist/core/learning/session-learning-decision.js.map +1 -1
  275. package/dist/core/memory-controller.d.ts.map +1 -1
  276. package/dist/core/memory-controller.js +4 -4
  277. package/dist/core/memory-controller.js.map +1 -1
  278. package/dist/core/model-capability.d.ts.map +1 -1
  279. package/dist/core/model-capability.js +1 -0
  280. package/dist/core/model-capability.js.map +1 -1
  281. package/dist/core/model-resolver.d.ts +1 -1
  282. package/dist/core/model-resolver.d.ts.map +1 -1
  283. package/dist/core/model-resolver.js +6 -9
  284. package/dist/core/model-resolver.js.map +1 -1
  285. package/dist/core/model-router/intent-classifier.d.ts +1 -4
  286. package/dist/core/model-router/intent-classifier.d.ts.map +1 -1
  287. package/dist/core/model-router/intent-classifier.js +1 -156
  288. package/dist/core/model-router/intent-classifier.js.map +1 -1
  289. package/dist/core/model-router-controller.d.ts.map +1 -1
  290. package/dist/core/model-router-controller.js +2 -2
  291. package/dist/core/model-router-controller.js.map +1 -1
  292. package/dist/core/model-selection-controller.d.ts +4 -4
  293. package/dist/core/model-selection-controller.d.ts.map +1 -1
  294. package/dist/core/model-selection-controller.js.map +1 -1
  295. package/dist/core/model-tool-protocol.d.ts +23 -0
  296. package/dist/core/model-tool-protocol.d.ts.map +1 -0
  297. package/dist/core/model-tool-protocol.js +43 -0
  298. package/dist/core/model-tool-protocol.js.map +1 -0
  299. package/dist/core/models/adaptation-store.d.ts +4 -6
  300. package/dist/core/models/adaptation-store.d.ts.map +1 -1
  301. package/dist/core/models/adaptation-store.js +95 -83
  302. package/dist/core/models/adaptation-store.js.map +1 -1
  303. package/dist/core/models/fitness-store.d.ts +2 -12
  304. package/dist/core/models/fitness-store.d.ts.map +1 -1
  305. package/dist/core/models/fitness-store.js +84 -57
  306. package/dist/core/models/fitness-store.js.map +1 -1
  307. package/dist/core/models/host-state-store.d.ts +34 -0
  308. package/dist/core/models/host-state-store.d.ts.map +1 -0
  309. package/dist/core/models/host-state-store.js +86 -0
  310. package/dist/core/models/host-state-store.js.map +1 -0
  311. package/dist/core/orchestration/agent-resume.d.ts +24 -0
  312. package/dist/core/orchestration/agent-resume.d.ts.map +1 -0
  313. package/dist/core/orchestration/agent-resume.js +90 -0
  314. package/dist/core/orchestration/agent-resume.js.map +1 -0
  315. package/dist/core/orchestration/capability-gateway.d.ts +61 -0
  316. package/dist/core/orchestration/capability-gateway.d.ts.map +1 -0
  317. package/dist/core/orchestration/capability-gateway.js +152 -0
  318. package/dist/core/orchestration/capability-gateway.js.map +1 -0
  319. package/dist/core/orchestration/contracts.d.ts +343 -0
  320. package/dist/core/orchestration/contracts.d.ts.map +1 -0
  321. package/dist/core/orchestration/contracts.js +135 -0
  322. package/dist/core/orchestration/contracts.js.map +1 -0
  323. package/dist/core/orchestration/delegation-ledger.d.ts +56 -0
  324. package/dist/core/orchestration/delegation-ledger.d.ts.map +1 -0
  325. package/dist/core/orchestration/delegation-ledger.js +197 -0
  326. package/dist/core/orchestration/delegation-ledger.js.map +1 -0
  327. package/dist/core/orchestration/event-store.d.ts +83 -0
  328. package/dist/core/orchestration/event-store.d.ts.map +1 -0
  329. package/dist/core/orchestration/event-store.js +560 -0
  330. package/dist/core/orchestration/event-store.js.map +1 -0
  331. package/dist/core/orchestration/lane-tool-manifests.d.ts +9 -0
  332. package/dist/core/orchestration/lane-tool-manifests.d.ts.map +1 -0
  333. package/dist/core/orchestration/lane-tool-manifests.js +37 -0
  334. package/dist/core/orchestration/lane-tool-manifests.js.map +1 -0
  335. package/dist/core/orchestration/model-binding.d.ts +15 -0
  336. package/dist/core/orchestration/model-binding.d.ts.map +1 -0
  337. package/dist/core/orchestration/model-binding.js +29 -0
  338. package/dist/core/orchestration/model-binding.js.map +1 -0
  339. package/dist/core/orchestration/policy-compiler.d.ts +49 -0
  340. package/dist/core/orchestration/policy-compiler.d.ts.map +1 -0
  341. package/dist/core/orchestration/policy-compiler.js +191 -0
  342. package/dist/core/orchestration/policy-compiler.js.map +1 -0
  343. package/dist/core/orchestration/policy-gate.d.ts +18 -0
  344. package/dist/core/orchestration/policy-gate.d.ts.map +1 -0
  345. package/dist/core/orchestration/policy-gate.js +24 -0
  346. package/dist/core/orchestration/policy-gate.js.map +1 -0
  347. package/dist/core/orchestration/profile-registry.d.ts +51 -0
  348. package/dist/core/orchestration/profile-registry.d.ts.map +1 -0
  349. package/dist/core/orchestration/profile-registry.js +393 -0
  350. package/dist/core/orchestration/profile-registry.js.map +1 -0
  351. package/dist/core/orchestration/profile-store.d.ts +31 -0
  352. package/dist/core/orchestration/profile-store.d.ts.map +1 -0
  353. package/dist/core/orchestration/profile-store.js +136 -0
  354. package/dist/core/orchestration/profile-store.js.map +1 -0
  355. package/dist/core/orchestration/risk-budget.d.ts +9 -0
  356. package/dist/core/orchestration/risk-budget.d.ts.map +1 -0
  357. package/dist/core/orchestration/risk-budget.js +48 -0
  358. package/dist/core/orchestration/risk-budget.js.map +1 -0
  359. package/dist/core/orchestration/task-runtime.d.ts +168 -0
  360. package/dist/core/orchestration/task-runtime.d.ts.map +1 -0
  361. package/dist/core/orchestration/task-runtime.js +1600 -0
  362. package/dist/core/orchestration/task-runtime.js.map +1 -0
  363. package/dist/core/orchestration/work-state-projection.d.ts +32 -0
  364. package/dist/core/orchestration/work-state-projection.d.ts.map +1 -0
  365. package/dist/core/orchestration/work-state-projection.js +116 -0
  366. package/dist/core/orchestration/work-state-projection.js.map +1 -0
  367. package/dist/core/orchestration/worker-execution-contract.d.ts +21 -0
  368. package/dist/core/orchestration/worker-execution-contract.d.ts.map +1 -0
  369. package/dist/core/orchestration/worker-execution-contract.js +179 -0
  370. package/dist/core/orchestration/worker-execution-contract.js.map +1 -0
  371. package/dist/core/orchestration/worker-result-adapter.d.ts +21 -0
  372. package/dist/core/orchestration/worker-result-adapter.d.ts.map +1 -0
  373. package/dist/core/orchestration/worker-result-adapter.js +109 -0
  374. package/dist/core/orchestration/worker-result-adapter.js.map +1 -0
  375. package/dist/core/process-identity.d.ts +11 -0
  376. package/dist/core/process-identity.d.ts.map +1 -0
  377. package/dist/core/process-identity.js +26 -0
  378. package/dist/core/process-identity.js.map +1 -0
  379. package/dist/core/process-matrix/codes.d.ts +14 -3
  380. package/dist/core/process-matrix/codes.d.ts.map +1 -1
  381. package/dist/core/process-matrix/codes.js.map +1 -1
  382. package/dist/core/process-matrix/resume-launcher.d.ts +26 -0
  383. package/dist/core/process-matrix/resume-launcher.d.ts.map +1 -0
  384. package/dist/core/process-matrix/resume-launcher.js +62 -0
  385. package/dist/core/process-matrix/resume-launcher.js.map +1 -0
  386. package/dist/core/process-matrix/runtime.d.ts +37 -22
  387. package/dist/core/process-matrix/runtime.d.ts.map +1 -1
  388. package/dist/core/process-matrix/runtime.js +399 -76
  389. package/dist/core/process-matrix/runtime.js.map +1 -1
  390. package/dist/core/process-matrix/store.d.ts +5 -2
  391. package/dist/core/process-matrix/store.d.ts.map +1 -1
  392. package/dist/core/process-matrix/store.js +123 -14
  393. package/dist/core/process-matrix/store.js.map +1 -1
  394. package/dist/core/process-matrix/supervisor.d.ts +10 -7
  395. package/dist/core/process-matrix/supervisor.d.ts.map +1 -1
  396. package/dist/core/process-matrix/supervisor.js +45 -14
  397. package/dist/core/process-matrix/supervisor.js.map +1 -1
  398. package/dist/core/profile-registry.d.ts.map +1 -1
  399. package/dist/core/profile-registry.js +6 -8
  400. package/dist/core/profile-registry.js.map +1 -1
  401. package/dist/core/reflection-controller.d.ts +4 -4
  402. package/dist/core/reflection-controller.d.ts.map +1 -1
  403. package/dist/core/reflection-controller.js +2 -1
  404. package/dist/core/reflection-controller.js.map +1 -1
  405. package/dist/core/reload-blockers.d.ts.map +1 -1
  406. package/dist/core/reload-blockers.js +6 -8
  407. package/dist/core/reload-blockers.js.map +1 -1
  408. package/dist/core/research/evidence-bundle.d.ts.map +1 -1
  409. package/dist/core/research/evidence-bundle.js +1 -6
  410. package/dist/core/research/evidence-bundle.js.map +1 -1
  411. package/dist/core/research/lane-model-resolver.d.ts +33 -0
  412. package/dist/core/research/lane-model-resolver.d.ts.map +1 -0
  413. package/dist/core/research/lane-model-resolver.js +65 -0
  414. package/dist/core/research/lane-model-resolver.js.map +1 -0
  415. package/dist/core/research/model-fitness-controller.d.ts +38 -0
  416. package/dist/core/research/model-fitness-controller.d.ts.map +1 -0
  417. package/dist/core/research/model-fitness-controller.js +106 -0
  418. package/dist/core/research/model-fitness-controller.js.map +1 -0
  419. package/dist/core/research/model-fitness.d.ts +1 -1
  420. package/dist/core/research/model-fitness.d.ts.map +1 -1
  421. package/dist/core/research/model-fitness.js +4 -4
  422. package/dist/core/research/model-fitness.js.map +1 -1
  423. package/dist/core/research/research-gate.d.ts.map +1 -1
  424. package/dist/core/research/research-gate.js +7 -7
  425. package/dist/core/research/research-gate.js.map +1 -1
  426. package/dist/core/research/research-lane-controller.d.ts +62 -0
  427. package/dist/core/research/research-lane-controller.d.ts.map +1 -0
  428. package/dist/core/research/research-lane-controller.js +292 -0
  429. package/dist/core/research/research-lane-controller.js.map +1 -0
  430. package/dist/core/research/session-evidence-bundle.d.ts +2 -4
  431. package/dist/core/research/session-evidence-bundle.d.ts.map +1 -1
  432. package/dist/core/research/session-evidence-bundle.js +10 -46
  433. package/dist/core/research/session-evidence-bundle.js.map +1 -1
  434. package/dist/core/resource-loader.d.ts.map +1 -1
  435. package/dist/core/resource-loader.js +7 -2
  436. package/dist/core/resource-loader.js.map +1 -1
  437. package/dist/core/risk-classifier.d.ts +6 -0
  438. package/dist/core/risk-classifier.d.ts.map +1 -0
  439. package/dist/core/risk-classifier.js +225 -0
  440. package/dist/core/risk-classifier.js.map +1 -0
  441. package/dist/core/runtime-builder.d.ts +26 -20
  442. package/dist/core/runtime-builder.d.ts.map +1 -1
  443. package/dist/core/runtime-builder.js +237 -178
  444. package/dist/core/runtime-builder.js.map +1 -1
  445. package/dist/core/sdk.d.ts +6 -3
  446. package/dist/core/sdk.d.ts.map +1 -1
  447. package/dist/core/sdk.js +61 -24
  448. package/dist/core/sdk.js.map +1 -1
  449. package/dist/core/session-analytics.d.ts.map +1 -1
  450. package/dist/core/session-analytics.js +28 -1
  451. package/dist/core/session-analytics.js.map +1 -1
  452. package/dist/core/session-image-store.d.ts +33 -0
  453. package/dist/core/session-image-store.d.ts.map +1 -0
  454. package/dist/core/session-image-store.js +283 -0
  455. package/dist/core/session-image-store.js.map +1 -0
  456. package/dist/core/session-role.d.ts +6 -4
  457. package/dist/core/session-role.d.ts.map +1 -1
  458. package/dist/core/session-role.js +10 -4
  459. package/dist/core/session-role.js.map +1 -1
  460. package/dist/core/session-snapshot.d.ts +34 -0
  461. package/dist/core/session-snapshot.d.ts.map +1 -0
  462. package/dist/core/session-snapshot.js +68 -0
  463. package/dist/core/session-snapshot.js.map +1 -0
  464. package/dist/core/session-supervision-runtime.d.ts +31 -0
  465. package/dist/core/session-supervision-runtime.d.ts.map +1 -0
  466. package/dist/core/session-supervision-runtime.js +97 -0
  467. package/dist/core/session-supervision-runtime.js.map +1 -0
  468. package/dist/core/settings-manager.d.ts +9 -4
  469. package/dist/core/settings-manager.d.ts.map +1 -1
  470. package/dist/core/settings-manager.js +80 -28
  471. package/dist/core/settings-manager.js.map +1 -1
  472. package/dist/core/tasks/session-task-state.d.ts +2 -4
  473. package/dist/core/tasks/session-task-state.d.ts.map +1 -1
  474. package/dist/core/tasks/session-task-state.js +10 -28
  475. package/dist/core/tasks/session-task-state.js.map +1 -1
  476. package/dist/core/tasks/task-projection.d.ts +20 -0
  477. package/dist/core/tasks/task-projection.d.ts.map +1 -0
  478. package/dist/core/tasks/task-projection.js +47 -0
  479. package/dist/core/tasks/task-projection.js.map +1 -0
  480. package/dist/core/tasks/task-state.d.ts +4 -0
  481. package/dist/core/tasks/task-state.d.ts.map +1 -1
  482. package/dist/core/tasks/task-state.js +28 -11
  483. package/dist/core/tasks/task-state.js.map +1 -1
  484. package/dist/core/tool-capability-policy.d.ts +13 -0
  485. package/dist/core/tool-capability-policy.d.ts.map +1 -0
  486. package/dist/core/tool-capability-policy.js +85 -0
  487. package/dist/core/tool-capability-policy.js.map +1 -0
  488. package/dist/core/tool-protocol-controller.d.ts +91 -0
  489. package/dist/core/tool-protocol-controller.d.ts.map +1 -0
  490. package/dist/core/tool-protocol-controller.js +512 -0
  491. package/dist/core/tool-protocol-controller.js.map +1 -0
  492. package/dist/core/tool-recovery-log-records.d.ts +2 -3
  493. package/dist/core/tool-recovery-log-records.d.ts.map +1 -1
  494. package/dist/core/tool-recovery-log-records.js +9 -35
  495. package/dist/core/tool-recovery-log-records.js.map +1 -1
  496. package/dist/core/tool-selection/tool-performance-store.d.ts +3 -7
  497. package/dist/core/tool-selection/tool-performance-store.d.ts.map +1 -1
  498. package/dist/core/tool-selection/tool-performance-store.js +97 -138
  499. package/dist/core/tool-selection/tool-performance-store.js.map +1 -1
  500. package/dist/core/tools/ask-question.d.ts +124 -0
  501. package/dist/core/tools/ask-question.d.ts.map +1 -0
  502. package/dist/core/tools/ask-question.js +693 -0
  503. package/dist/core/tools/ask-question.js.map +1 -0
  504. package/dist/core/tools/delegate-status.d.ts +31 -3
  505. package/dist/core/tools/delegate-status.d.ts.map +1 -1
  506. package/dist/core/tools/delegate-status.js +149 -29
  507. package/dist/core/tools/delegate-status.js.map +1 -1
  508. package/dist/core/tools/delegate.d.ts +15 -13
  509. package/dist/core/tools/delegate.d.ts.map +1 -1
  510. package/dist/core/tools/delegate.js +108 -23
  511. package/dist/core/tools/delegate.js.map +1 -1
  512. package/dist/core/tools/extensionify.d.ts.map +1 -1
  513. package/dist/core/tools/extensionify.js +1 -0
  514. package/dist/core/tools/extensionify.js.map +1 -1
  515. package/dist/core/tools/goal.d.ts +5 -5
  516. package/dist/core/tools/goal.d.ts.map +1 -1
  517. package/dist/core/tools/goal.js +10 -10
  518. package/dist/core/tools/goal.js.map +1 -1
  519. package/dist/core/tools/model-fitness.d.ts.map +1 -1
  520. package/dist/core/tools/model-fitness.js +2 -2
  521. package/dist/core/tools/model-fitness.js.map +1 -1
  522. package/dist/core/tools/orchestration-panel.d.ts +43 -0
  523. package/dist/core/tools/orchestration-panel.d.ts.map +1 -0
  524. package/dist/core/tools/orchestration-panel.js +168 -0
  525. package/dist/core/tools/orchestration-panel.js.map +1 -0
  526. package/dist/core/tools/run-process.d.ts +26 -0
  527. package/dist/core/tools/run-process.d.ts.map +1 -0
  528. package/dist/core/tools/run-process.js +138 -0
  529. package/dist/core/tools/run-process.js.map +1 -0
  530. package/dist/core/tools/task-steps.d.ts +2 -0
  531. package/dist/core/tools/task-steps.d.ts.map +1 -1
  532. package/dist/core/tools/task-steps.js +102 -0
  533. package/dist/core/tools/task-steps.js.map +1 -1
  534. package/dist/core/tools/tmux-dispatch.d.ts +3 -5
  535. package/dist/core/tools/tmux-dispatch.d.ts.map +1 -1
  536. package/dist/core/tools/tmux-dispatch.js +4 -4
  537. package/dist/core/tools/tmux-dispatch.js.map +1 -1
  538. package/dist/core/tools/windows-shell-engine.d.ts.map +1 -1
  539. package/dist/core/tools/windows-shell-engine.js +4 -6
  540. package/dist/core/tools/windows-shell-engine.js.map +1 -1
  541. package/dist/core/util/bounded-jsonl.d.ts +10 -0
  542. package/dist/core/util/bounded-jsonl.d.ts.map +1 -0
  543. package/dist/core/util/bounded-jsonl.js +75 -0
  544. package/dist/core/util/bounded-jsonl.js.map +1 -0
  545. package/dist/core/util/value-guards.d.ts +5 -0
  546. package/dist/core/util/value-guards.d.ts.map +1 -0
  547. package/dist/core/util/value-guards.js +12 -0
  548. package/dist/core/util/value-guards.js.map +1 -0
  549. package/dist/core/worktree-sync/store.d.ts +3 -3
  550. package/dist/core/worktree-sync/store.d.ts.map +1 -1
  551. package/dist/core/worktree-sync/store.js +10 -5
  552. package/dist/core/worktree-sync/store.js.map +1 -1
  553. package/dist/index.d.ts +13 -3
  554. package/dist/index.d.ts.map +1 -1
  555. package/dist/index.js +12 -2
  556. package/dist/index.js.map +1 -1
  557. package/dist/main.d.ts.map +1 -1
  558. package/dist/main.js +128 -44
  559. package/dist/main.js.map +1 -1
  560. package/dist/migrations.d.ts +4 -6
  561. package/dist/migrations.d.ts.map +1 -1
  562. package/dist/migrations.js +186 -28
  563. package/dist/migrations.js.map +1 -1
  564. package/dist/modes/interactive/clipboard-input.d.ts +7 -1
  565. package/dist/modes/interactive/clipboard-input.d.ts.map +1 -1
  566. package/dist/modes/interactive/clipboard-input.js +44 -6
  567. package/dist/modes/interactive/clipboard-input.js.map +1 -1
  568. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  569. package/dist/modes/interactive/components/settings-selector.js +2 -2
  570. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  571. package/dist/modes/interactive/config-backup.d.ts.map +1 -1
  572. package/dist/modes/interactive/config-backup.js +5 -4
  573. package/dist/modes/interactive/config-backup.js.map +1 -1
  574. package/dist/modes/interactive/extension-ui-host.d.ts +14 -0
  575. package/dist/modes/interactive/extension-ui-host.d.ts.map +1 -1
  576. package/dist/modes/interactive/extension-ui-host.js +76 -15
  577. package/dist/modes/interactive/extension-ui-host.js.map +1 -1
  578. package/dist/modes/interactive/interactive-mode.d.ts +3 -0
  579. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  580. package/dist/modes/interactive/interactive-mode.js +63 -1
  581. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  582. package/dist/modes/interactive/key-handlers.d.ts.map +1 -1
  583. package/dist/modes/interactive/key-handlers.js +1 -1
  584. package/dist/modes/interactive/key-handlers.js.map +1 -1
  585. package/dist/modes/interactive/profile-menu-controller.d.ts.map +1 -1
  586. package/dist/modes/interactive/profile-menu-controller.js +7 -7
  587. package/dist/modes/interactive/profile-menu-controller.js.map +1 -1
  588. package/dist/modes/interactive/report-commands.d.ts.map +1 -1
  589. package/dist/modes/interactive/report-commands.js +21 -0
  590. package/dist/modes/interactive/report-commands.js.map +1 -1
  591. package/dist/modes/interactive/session-flow-commands.d.ts +17 -2
  592. package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -1
  593. package/dist/modes/interactive/session-flow-commands.js +50 -17
  594. package/dist/modes/interactive/session-flow-commands.js.map +1 -1
  595. package/dist/modes/interactive/session-io-commands.d.ts.map +1 -1
  596. package/dist/modes/interactive/session-io-commands.js +16 -6
  597. package/dist/modes/interactive/session-io-commands.js.map +1 -1
  598. package/dist/modes/interactive/session-replacement-errors.d.ts +7 -0
  599. package/dist/modes/interactive/session-replacement-errors.d.ts.map +1 -0
  600. package/dist/modes/interactive/session-replacement-errors.js +15 -0
  601. package/dist/modes/interactive/session-replacement-errors.js.map +1 -0
  602. package/dist/modes/interactive/startup-checks.d.ts.map +1 -1
  603. package/dist/modes/interactive/startup-checks.js +1 -1
  604. package/dist/modes/interactive/startup-checks.js.map +1 -1
  605. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  606. package/dist/modes/rpc/rpc-mode.js +82 -23
  607. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  608. package/dist/modes/rpc/rpc-types.d.ts +15 -0
  609. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  610. package/dist/modes/rpc/rpc-types.js +138 -1
  611. package/dist/modes/rpc/rpc-types.js.map +1 -1
  612. package/dist/utils/clipboard-image.d.ts.map +1 -1
  613. package/dist/utils/clipboard-image.js +2 -13
  614. package/dist/utils/clipboard-image.js.map +1 -1
  615. package/dist/utils/clipboard-native.d.ts +1 -0
  616. package/dist/utils/clipboard-native.d.ts.map +1 -1
  617. package/dist/utils/clipboard-native.js.map +1 -1
  618. package/dist/utils/clipboard.d.ts +1 -0
  619. package/dist/utils/clipboard.d.ts.map +1 -1
  620. package/dist/utils/clipboard.js +52 -1
  621. package/dist/utils/clipboard.js.map +1 -1
  622. package/dist/utils/platform.d.ts +3 -0
  623. package/dist/utils/platform.d.ts.map +1 -0
  624. package/dist/utils/platform.js +8 -0
  625. package/dist/utils/platform.js.map +1 -0
  626. package/dist/utils/work-directory.d.ts +11 -0
  627. package/dist/utils/work-directory.d.ts.map +1 -1
  628. package/dist/utils/work-directory.js +30 -9
  629. package/dist/utils/work-directory.js.map +1 -1
  630. package/docs/UI_POLISH_ORCHESTRATION.md +44 -0
  631. package/docs/UI_QUALITY_ORCHESTRATION.md +30 -0
  632. package/docs/docs.json +4 -0
  633. package/docs/extensions.md +62 -2
  634. package/docs/harness-architecture.md +156 -0
  635. package/docs/keybindings.md +11 -1
  636. package/docs/process-matrix.md +59 -26
  637. package/docs/rpc.md +45 -2
  638. package/docs/sessions.md +15 -0
  639. package/docs/settings.md +125 -11
  640. package/docs/task-steps.md +8 -0
  641. package/docs/telemetry.md +19 -0
  642. package/docs/tmux-agent-manager.md +10 -3
  643. package/docs/ui-reference/README.md +9 -0
  644. package/docs/ui-reference/orchestration-after.txt +7 -0
  645. package/docs/ui-reference/orchestration-before.txt +7 -0
  646. package/docs/ui-reference/orchestration-reference.txt +6 -0
  647. package/docs/usage.md +14 -2
  648. package/docs/work-directory.md +19 -8
  649. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  650. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  651. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  652. package/examples/extensions/question.ts +34 -245
  653. package/examples/extensions/questionnaire.ts +41 -407
  654. package/examples/extensions/sandbox/package-lock.json +2 -2
  655. package/examples/extensions/sandbox/package.json +1 -1
  656. package/examples/extensions/with-deps/package-lock.json +2 -2
  657. package/examples/extensions/with-deps/package.json +1 -1
  658. package/npm-shrinkwrap.json +12 -12
  659. package/package.json +4 -4
  660. package/dist/core/delegation/session-worker-result.d.ts +0 -46
  661. package/dist/core/delegation/session-worker-result.d.ts.map +0 -1
  662. package/dist/core/delegation/session-worker-result.js +0 -113
  663. package/dist/core/delegation/session-worker-result.js.map +0 -1
  664. package/dist/core/delegation/worker-result.d.ts.map +0 -1
  665. package/dist/core/delegation/worker-result.js.map +0 -1
  666. package/dist/core/telemetry.d.ts.map +0 -1
  667. package/dist/core/telemetry.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"gates.js","sourceRoot":"","sources":["../../../src/core/autonomy/gates.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\nimport { hasCapabilityPolicyForTool, requiredCapabilitiesForTool } from \"./approval-gate.ts\";\nimport type { CapabilityEnvelope, GateOutcome, GateOutcomeKind } from \"./contracts.ts\";\nimport { checkPathScope } from \"./path-scope.ts\";\nimport { assessOperationRisk } from \"./risk-assessment.ts\";\n\nfunction isGateOutcomeKind(value: unknown): value is GateOutcomeKind {\n\treturn (\n\t\tvalue === \"allow\" || value === \"downgrade\" || value === \"escalate\" || value === \"ask-user\" || value === \"block\"\n\t);\n}\n\nfunction getPrecedence(kind: unknown): number {\n\tif (kind === \"allow\") return 0;\n\tif (kind === \"downgrade\") return 1;\n\tif (kind === \"escalate\") return 2;\n\tif (kind === \"ask-user\") return 3;\n\tif (kind === \"block\") return 4;\n\treturn 4; // Malformed/unknown outcome kind defaults to most restrictive (block)\n}\n\nexport function combineGateOutcomes(outcomes: readonly GateOutcome[]): GateOutcome {\n\tif (outcomes.length === 0) {\n\t\treturn {\n\t\t\toutcome: \"ask-user\",\n\t\t\tgate: \"gate-combiner\",\n\t\t\treasonCode: \"no_gate_outcomes\",\n\t\t\tmessage: \"No gate outcomes to combine\",\n\t\t};\n\t}\n\n\tlet winner = outcomes[0];\n\tlet maxPrecedence = getPrecedence(winner.outcome);\n\n\tfor (let i = 1; i < outcomes.length; i++) {\n\t\tconst current = outcomes[i];\n\t\tconst currentPrecedence = getPrecedence(current.outcome);\n\t\tif (currentPrecedence > maxPrecedence) {\n\t\t\twinner = current;\n\t\t\tmaxPrecedence = currentPrecedence;\n\t\t}\n\t}\n\n\tif (!isGateOutcomeKind(winner.outcome)) {\n\t\treturn {\n\t\t\t...winner,\n\t\t\toutcome: \"block\",\n\t\t\tmessage: winner.message || \"Malformed outcome kind coerced to block\",\n\t\t};\n\t}\n\n\treturn winner;\n}\n\nexport function fallbackGateOutcome(args: { gate: string; reversible: boolean; reasonCode: string }): GateOutcome {\n\tconst gate = (args.gate || \"\").trim() || \"unknown_gate\";\n\tconst reasonCode = (args.reasonCode || \"\").trim() || \"unknown_reason\";\n\tconst outcome: GateOutcomeKind = args.reversible ? \"ask-user\" : \"block\";\n\n\treturn {\n\t\toutcome,\n\t\tgate,\n\t\treasonCode,\n\t\tmessage: `Fallback gate outcome: ${outcome} for gate ${gate} (${reasonCode})`,\n\t};\n}\n\nexport function extractCandidatePaths(toolName: string, args: unknown): string[] {\n\tif (!args || typeof args !== \"object\") return [];\n\tconst obj = args as Record<string, unknown>;\n\tconst paths: string[] = [];\n\n\tif (\n\t\ttoolName === \"read\" ||\n\t\ttoolName === \"write\" ||\n\t\ttoolName === \"edit\" ||\n\t\ttoolName === \"ls\" ||\n\t\ttoolName === \"grep\" ||\n\t\ttoolName === \"find\"\n\t) {\n\t\tif (typeof obj.path === \"string\" && obj.path.trim()) {\n\t\t\tpaths.push(obj.path.trim());\n\t\t}\n\t}\n\n\treturn paths;\n}\n\nexport function evaluateToolGate(input: {\n\ttoolName: string;\n\targs?: unknown;\n\tcwd: string;\n\tenvelope?: CapabilityEnvelope;\n}): GateOutcome {\n\tif (!input.envelope) {\n\t\treturn {\n\t\t\toutcome: \"allow\",\n\t\t\tgate: \"tool_gate\",\n\t\t\treasonCode: \"no_envelope\",\n\t\t\tmessage: \"No envelope active, preserving existing session behavior.\",\n\t\t};\n\t}\n\n\tconst envelope = input.envelope;\n\n\t// 1. Tool allow/deny list overrides\n\tif (envelope.deniedTools?.includes(input.toolName)) {\n\t\treturn {\n\t\t\toutcome: \"block\",\n\t\t\tgate: \"tool_gate\",\n\t\t\treasonCode: \"tool_denied\",\n\t\t\tmessage: `Tool '${input.toolName}' is explicitly denied.`,\n\t\t};\n\t}\n\n\tif (envelope.allowedTools && !envelope.allowedTools.includes(input.toolName)) {\n\t\treturn {\n\t\t\toutcome: \"block\",\n\t\t\tgate: \"tool_gate\",\n\t\t\treasonCode: \"tool_not_allowed\",\n\t\t\tmessage: `Tool '${input.toolName}' is not in the allowed tools list.`,\n\t\t};\n\t}\n\n\t// 2. Path scope containment for file tools\n\tconst paths = extractCandidatePaths(input.toolName, input.args);\n\tif (paths.length > 0 && envelope.allowedPaths) {\n\t\t// If envelope has allowedPaths, we must check them\n\t\tfor (const targetPath of paths) {\n\t\t\tconst scopedTargetPath = path.isAbsolute(targetPath) ? targetPath : path.resolve(input.cwd, targetPath);\n\t\t\tlet isInsideAny = false;\n\t\t\tlet isDenied = false;\n\t\t\tlet denyRule = \"\";\n\n\t\t\tfor (const allowedRoot of envelope.allowedPaths) {\n\t\t\t\tconst decision = checkPathScope(\n\t\t\t\t\t{\n\t\t\t\t\t\troot: allowedRoot,\n\t\t\t\t\t\tallowedPaths: envelope.allowedPaths,\n\t\t\t\t\t\tdeniedPaths: envelope.deniedPaths,\n\t\t\t\t\t},\n\t\t\t\t\tscopedTargetPath,\n\t\t\t\t);\n\n\t\t\t\tif (decision.kind === \"denied\") {\n\t\t\t\t\tisDenied = true;\n\t\t\t\t\tdenyRule = decision.matchedRule || \"\";\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (decision.kind === \"inside\") {\n\t\t\t\t\tisInsideAny = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isDenied) {\n\t\t\t\treturn {\n\t\t\t\t\toutcome: \"block\",\n\t\t\t\t\tgate: \"path_scope\",\n\t\t\t\t\treasonCode: \"path_denied\",\n\t\t\t\t\tmessage: `Path '${targetPath}' is explicitly denied by rule '${denyRule}'.`,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (!isInsideAny) {\n\t\t\t\t// Block only if the tool is mutating. Wait, read path outside allowed root -> block.\n\t\t\t\t// \"read path inside allowed root -> allow. write/edit path outside allowed root -> block. denied path inside allowed root -> block.\"\n\t\t\t\treturn {\n\t\t\t\t\toutcome: \"block\",\n\t\t\t\t\tgate: \"path_scope\",\n\t\t\t\t\treasonCode: \"path_outside_allowed_roots\",\n\t\t\t\t\tmessage: `Path '${targetPath}' is outside all allowed roots.`,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2.5. Capability checks\n\tif (!hasCapabilityPolicyForTool(input.toolName)) {\n\t\treturn {\n\t\t\toutcome: \"block\",\n\t\t\tgate: \"tool_gate\",\n\t\t\treasonCode: \"unknown_tool_capability\",\n\t\t\tmessage: `Tool '${input.toolName}' has no capability policy in the active envelope.`,\n\t\t};\n\t}\n\n\tconst requiredCaps = requiredCapabilitiesForTool(input.toolName, input.args);\n\tfor (const reqCap of requiredCaps) {\n\t\tif (!envelope.capabilities.includes(reqCap)) {\n\t\t\treturn {\n\t\t\t\toutcome: \"block\",\n\t\t\t\tgate: \"tool_gate\",\n\t\t\t\treasonCode: \"missing_capability\",\n\t\t\t\tmessage: `Tool '${input.toolName}' requires capability '${reqCap}', which is missing from the active envelope.`,\n\t\t\t};\n\t\t}\n\t}\n\tlet command = \"\";\n\tif (\n\t\tinput.toolName === \"bash\" ||\n\t\tinput.toolName === \"powershell\" ||\n\t\tinput.toolName === \"shell\" ||\n\t\tinput.toolName === \"python\"\n\t) {\n\t\tconst argsObj = input.args as Record<string, unknown>;\n\t\tif (argsObj && typeof argsObj.command === \"string\") command = argsObj.command;\n\t\telse if (input.toolName === \"python\" && argsObj && typeof argsObj.code === \"string\") command = argsObj.code;\n\t\telse if (input.toolName === \"python\" && argsObj && typeof argsObj.scriptPath === \"string\") {\n\t\t\tcommand = `python ${argsObj.scriptPath}`;\n\t\t}\n\t}\n\n\tconst riskResult = assessOperationRisk({\n\t\toperation: `Tool ${input.toolName}`,\n\t\ttoolName: input.toolName,\n\t\tcommand,\n\t\tpaths,\n\t\tcapabilities: envelope.capabilities,\n\t});\n\n\tif (riskResult.requiresApproval) {\n\t\treturn {\n\t\t\toutcome: \"ask-user\", // or block, prompt says: ask-user/block\n\t\t\tgate: \"risk_assessment\",\n\t\t\treasonCode: riskResult.reasonCode,\n\t\t\tmessage: `Operation requires approval: ${riskResult.reasons.join(\", \")}`,\n\t\t};\n\t}\n\n\tif (riskResult.risk === \"high-impact\") {\n\t\treturn {\n\t\t\toutcome: \"ask-user\",\n\t\t\tgate: \"risk_assessment\",\n\t\t\treasonCode: riskResult.reasonCode,\n\t\t\tmessage: `High-impact operation requires review: ${riskResult.reasons.join(\", \")}`,\n\t\t};\n\t}\n\n\treturn {\n\t\toutcome: \"allow\",\n\t\tgate: \"tool_gate\",\n\t\treasonCode: \"allowed_by_envelope\",\n\t\tmessage: \"Operation allowed by current capability envelope.\",\n\t};\n}\n"]}
1
+ {"version":3,"file":"gates.js","sourceRoot":"","sources":["../../../src/core/autonomy/gates.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EACN,0BAA0B,EAC1B,4BAA4B,EAC5B,2BAA2B,GAC3B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,SAAS,iBAAiB,CAAC,KAAc,EAA4B;IACpE,OAAO,CACN,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,OAAO,CAC/G,CAAC;AAAA,CACF;AAED,SAAS,aAAa,CAAC,IAAa,EAAU;IAC7C,IAAI,IAAI,KAAK,OAAO;QAAE,OAAO,CAAC,CAAC;IAC/B,IAAI,IAAI,KAAK,WAAW;QAAE,OAAO,CAAC,CAAC;IACnC,IAAI,IAAI,KAAK,UAAU;QAAE,OAAO,CAAC,CAAC;IAClC,IAAI,IAAI,KAAK,UAAU;QAAE,OAAO,CAAC,CAAC;IAClC,IAAI,IAAI,KAAK,OAAO;QAAE,OAAO,CAAC,CAAC;IAC/B,OAAO,CAAC,CAAC,CAAC,sEAAsE;AAAvE,CACT;AAED,MAAM,UAAU,mBAAmB,CAAC,QAAgC,EAAe;IAClF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO;YACN,OAAO,EAAE,UAAU;YACnB,IAAI,EAAE,eAAe;YACrB,UAAU,EAAE,kBAAkB;YAC9B,OAAO,EAAE,6BAA6B;SACtC,CAAC;IACH,CAAC;IAED,IAAI,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAElD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,iBAAiB,GAAG,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACzD,IAAI,iBAAiB,GAAG,aAAa,EAAE,CAAC;YACvC,MAAM,GAAG,OAAO,CAAC;YACjB,aAAa,GAAG,iBAAiB,CAAC;QACnC,CAAC;IACF,CAAC;IAED,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,OAAO;YACN,GAAG,MAAM;YACT,OAAO,EAAE,OAAO;YAChB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,yCAAyC;SACpE,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAAA,CACd;AAED,MAAM,UAAU,mBAAmB,CAAC,IAA+D,EAAe;IACjH,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,cAAc,CAAC;IACxD,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,gBAAgB,CAAC;IACtE,MAAM,OAAO,GAAoB,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;IAExE,OAAO;QACN,OAAO;QACP,IAAI;QACJ,UAAU;QACV,OAAO,EAAE,0BAA0B,OAAO,aAAa,IAAI,KAAK,UAAU,GAAG;KAC7E,CAAC;AAAA,CACF;AAED,MAAM,UAAU,qBAAqB,CAAC,QAAgB,EAAE,IAAa,EAAY;IAChF,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACjD,MAAM,GAAG,GAAG,IAA+B,CAAC;IAC5C,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IACC,QAAQ,KAAK,MAAM;QACnB,QAAQ,KAAK,OAAO;QACpB,QAAQ,KAAK,MAAM;QACnB,QAAQ,KAAK,IAAI;QACjB,QAAQ,KAAK,MAAM;QACnB,QAAQ,KAAK,MAAM,EAClB,CAAC;QACF,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YACrD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7B,CAAC;IACF,CAAC;IAED,OAAO,KAAK,CAAC;AAAA,CACb;AAED,MAAM,UAAU,gBAAgB,CAAC,KAKhC,EAAe;IACf,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrB,OAAO;YACN,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,WAAW;YACjB,UAAU,EAAE,aAAa;YACzB,OAAO,EAAE,2DAA2D;SACpE,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAEhC,oCAAoC;IACpC,IAAI,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpD,OAAO;YACN,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,WAAW;YACjB,UAAU,EAAE,aAAa;YACzB,OAAO,EAAE,SAAS,KAAK,CAAC,QAAQ,yBAAyB;SACzD,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,YAAY,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9E,OAAO;YACN,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,WAAW;YACjB,UAAU,EAAE,kBAAkB;YAC9B,OAAO,EAAE,SAAS,KAAK,CAAC,QAAQ,qCAAqC;SACrE,CAAC;IACH,CAAC;IAED,2CAA2C;IAC3C,MAAM,KAAK,GAAG,qBAAqB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAChE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC;QAC/C,mDAAmD;QACnD,KAAK,MAAM,UAAU,IAAI,KAAK,EAAE,CAAC;YAChC,MAAM,gBAAgB,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;YACxG,IAAI,WAAW,GAAG,KAAK,CAAC;YACxB,IAAI,QAAQ,GAAG,KAAK,CAAC;YACrB,IAAI,QAAQ,GAAG,EAAE,CAAC;YAElB,KAAK,MAAM,WAAW,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC;gBACjD,MAAM,QAAQ,GAAG,cAAc,CAC9B;oBACC,IAAI,EAAE,WAAW;oBACjB,YAAY,EAAE,QAAQ,CAAC,YAAY;oBACnC,WAAW,EAAE,QAAQ,CAAC,WAAW;iBACjC,EACD,gBAAgB,CAChB,CAAC;gBAEF,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAChC,QAAQ,GAAG,IAAI,CAAC;oBAChB,QAAQ,GAAG,QAAQ,CAAC,WAAW,IAAI,EAAE,CAAC;oBACtC,MAAM;gBACP,CAAC;gBACD,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAChC,WAAW,GAAG,IAAI,CAAC;gBACpB,CAAC;YACF,CAAC;YAED,IAAI,QAAQ,EAAE,CAAC;gBACd,OAAO;oBACN,OAAO,EAAE,OAAO;oBAChB,IAAI,EAAE,YAAY;oBAClB,UAAU,EAAE,aAAa;oBACzB,OAAO,EAAE,SAAS,UAAU,mCAAmC,QAAQ,IAAI;iBAC3E,CAAC;YACH,CAAC;YAED,IAAI,CAAC,WAAW,EAAE,CAAC;gBAClB,qFAAqF;gBACrF,qIAAqI;gBACrI,OAAO;oBACN,OAAO,EAAE,OAAO;oBAChB,IAAI,EAAE,YAAY;oBAClB,UAAU,EAAE,4BAA4B;oBACxC,OAAO,EAAE,SAAS,UAAU,iCAAiC;iBAC7D,CAAC;YACH,CAAC;QACF,CAAC;IACF,CAAC;IAED,yBAAyB;IACzB,IAAI,CAAC,0BAA0B,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjD,OAAO;YACN,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,WAAW;YACjB,UAAU,EAAE,yBAAyB;YACrC,OAAO,EAAE,SAAS,KAAK,CAAC,QAAQ,oDAAoD;SACpF,CAAC;IACH,CAAC;IAED,MAAM,YAAY,GAAG,2BAA2B,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7E,IAAI,CAAC,4BAA4B,CAAC,QAAQ,CAAC,YAAY,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACtF,OAAO;YACN,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,WAAW;YACjB,UAAU,EAAE,oBAAoB;YAChC,OAAO,EAAE,SAAS,KAAK,CAAC,QAAQ,0BAA0B,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,+CAA+C;SAClI,CAAC;IACH,CAAC;IACD,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IACC,KAAK,CAAC,QAAQ,KAAK,MAAM;QACzB,KAAK,CAAC,QAAQ,KAAK,YAAY;QAC/B,KAAK,CAAC,QAAQ,KAAK,OAAO;QAC1B,KAAK,CAAC,QAAQ,KAAK,QAAQ,EAC1B,CAAC;QACF,MAAM,OAAO,GAAG,KAAK,CAAC,IAA+B,CAAC;QACtD,IAAI,OAAO,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ;YAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;aACzE,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ,IAAI,OAAO,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;aACvG,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ,IAAI,OAAO,IAAI,OAAO,OAAO,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;YAC3F,OAAO,GAAG,UAAU,OAAO,CAAC,UAAU,EAAE,CAAC;QAC1C,CAAC;IACF,CAAC;IAED,MAAM,UAAU,GAAG,mBAAmB,CAAC;QACtC,SAAS,EAAE,QAAQ,KAAK,CAAC,QAAQ,EAAE;QACnC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,OAAO;QACP,KAAK;QACL,YAAY,EAAE,QAAQ,CAAC,YAAY;KACnC,CAAC,CAAC;IAEH,IAAI,UAAU,CAAC,gBAAgB,EAAE,CAAC;QACjC,OAAO;YACN,OAAO,EAAE,UAAU,EAAE,wCAAwC;YAC7D,IAAI,EAAE,iBAAiB;YACvB,UAAU,EAAE,UAAU,CAAC,UAAU;YACjC,OAAO,EAAE,gCAAgC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SACxE,CAAC;IACH,CAAC;IAED,IAAI,UAAU,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;QACvC,OAAO;YACN,OAAO,EAAE,UAAU;YACnB,IAAI,EAAE,iBAAiB;YACvB,UAAU,EAAE,UAAU,CAAC,UAAU;YACjC,OAAO,EAAE,0CAA0C,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SAClF,CAAC;IACH,CAAC;IAED,OAAO;QACN,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,WAAW;QACjB,UAAU,EAAE,qBAAqB;QACjC,OAAO,EAAE,mDAAmD;KAC5D,CAAC;AAAA,CACF","sourcesContent":["import path from \"node:path\";\nimport {\n\thasCapabilityPolicyForTool,\n\thasRequiredCapabilityForTool,\n\trequiredCapabilitiesForTool,\n} from \"./approval-gate.ts\";\nimport type { CapabilityEnvelope, GateOutcome, GateOutcomeKind } from \"./contracts.ts\";\nimport { checkPathScope } from \"./path-scope.ts\";\nimport { assessOperationRisk } from \"./risk-assessment.ts\";\n\nfunction isGateOutcomeKind(value: unknown): value is GateOutcomeKind {\n\treturn (\n\t\tvalue === \"allow\" || value === \"downgrade\" || value === \"escalate\" || value === \"ask-user\" || value === \"block\"\n\t);\n}\n\nfunction getPrecedence(kind: unknown): number {\n\tif (kind === \"allow\") return 0;\n\tif (kind === \"downgrade\") return 1;\n\tif (kind === \"escalate\") return 2;\n\tif (kind === \"ask-user\") return 3;\n\tif (kind === \"block\") return 4;\n\treturn 4; // Malformed/unknown outcome kind defaults to most restrictive (block)\n}\n\nexport function combineGateOutcomes(outcomes: readonly GateOutcome[]): GateOutcome {\n\tif (outcomes.length === 0) {\n\t\treturn {\n\t\t\toutcome: \"ask-user\",\n\t\t\tgate: \"gate-combiner\",\n\t\t\treasonCode: \"no_gate_outcomes\",\n\t\t\tmessage: \"No gate outcomes to combine\",\n\t\t};\n\t}\n\n\tlet winner = outcomes[0];\n\tlet maxPrecedence = getPrecedence(winner.outcome);\n\n\tfor (let i = 1; i < outcomes.length; i++) {\n\t\tconst current = outcomes[i];\n\t\tconst currentPrecedence = getPrecedence(current.outcome);\n\t\tif (currentPrecedence > maxPrecedence) {\n\t\t\twinner = current;\n\t\t\tmaxPrecedence = currentPrecedence;\n\t\t}\n\t}\n\n\tif (!isGateOutcomeKind(winner.outcome)) {\n\t\treturn {\n\t\t\t...winner,\n\t\t\toutcome: \"block\",\n\t\t\tmessage: winner.message || \"Malformed outcome kind coerced to block\",\n\t\t};\n\t}\n\n\treturn winner;\n}\n\nexport function fallbackGateOutcome(args: { gate: string; reversible: boolean; reasonCode: string }): GateOutcome {\n\tconst gate = (args.gate || \"\").trim() || \"unknown_gate\";\n\tconst reasonCode = (args.reasonCode || \"\").trim() || \"unknown_reason\";\n\tconst outcome: GateOutcomeKind = args.reversible ? \"ask-user\" : \"block\";\n\n\treturn {\n\t\toutcome,\n\t\tgate,\n\t\treasonCode,\n\t\tmessage: `Fallback gate outcome: ${outcome} for gate ${gate} (${reasonCode})`,\n\t};\n}\n\nexport function extractCandidatePaths(toolName: string, args: unknown): string[] {\n\tif (!args || typeof args !== \"object\") return [];\n\tconst obj = args as Record<string, unknown>;\n\tconst paths: string[] = [];\n\n\tif (\n\t\ttoolName === \"read\" ||\n\t\ttoolName === \"write\" ||\n\t\ttoolName === \"edit\" ||\n\t\ttoolName === \"ls\" ||\n\t\ttoolName === \"grep\" ||\n\t\ttoolName === \"find\"\n\t) {\n\t\tif (typeof obj.path === \"string\" && obj.path.trim()) {\n\t\t\tpaths.push(obj.path.trim());\n\t\t}\n\t}\n\n\treturn paths;\n}\n\nexport function evaluateToolGate(input: {\n\ttoolName: string;\n\targs?: unknown;\n\tcwd: string;\n\tenvelope?: CapabilityEnvelope;\n}): GateOutcome {\n\tif (!input.envelope) {\n\t\treturn {\n\t\t\toutcome: \"allow\",\n\t\t\tgate: \"tool_gate\",\n\t\t\treasonCode: \"no_envelope\",\n\t\t\tmessage: \"No envelope active, preserving existing session behavior.\",\n\t\t};\n\t}\n\n\tconst envelope = input.envelope;\n\n\t// 1. Tool allow/deny list overrides\n\tif (envelope.deniedTools?.includes(input.toolName)) {\n\t\treturn {\n\t\t\toutcome: \"block\",\n\t\t\tgate: \"tool_gate\",\n\t\t\treasonCode: \"tool_denied\",\n\t\t\tmessage: `Tool '${input.toolName}' is explicitly denied.`,\n\t\t};\n\t}\n\n\tif (envelope.allowedTools && !envelope.allowedTools.includes(input.toolName)) {\n\t\treturn {\n\t\t\toutcome: \"block\",\n\t\t\tgate: \"tool_gate\",\n\t\t\treasonCode: \"tool_not_allowed\",\n\t\t\tmessage: `Tool '${input.toolName}' is not in the allowed tools list.`,\n\t\t};\n\t}\n\n\t// 2. Path scope containment for file tools\n\tconst paths = extractCandidatePaths(input.toolName, input.args);\n\tif (paths.length > 0 && envelope.allowedPaths) {\n\t\t// If envelope has allowedPaths, we must check them\n\t\tfor (const targetPath of paths) {\n\t\t\tconst scopedTargetPath = path.isAbsolute(targetPath) ? targetPath : path.resolve(input.cwd, targetPath);\n\t\t\tlet isInsideAny = false;\n\t\t\tlet isDenied = false;\n\t\t\tlet denyRule = \"\";\n\n\t\t\tfor (const allowedRoot of envelope.allowedPaths) {\n\t\t\t\tconst decision = checkPathScope(\n\t\t\t\t\t{\n\t\t\t\t\t\troot: allowedRoot,\n\t\t\t\t\t\tallowedPaths: envelope.allowedPaths,\n\t\t\t\t\t\tdeniedPaths: envelope.deniedPaths,\n\t\t\t\t\t},\n\t\t\t\t\tscopedTargetPath,\n\t\t\t\t);\n\n\t\t\t\tif (decision.kind === \"denied\") {\n\t\t\t\t\tisDenied = true;\n\t\t\t\t\tdenyRule = decision.matchedRule || \"\";\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (decision.kind === \"inside\") {\n\t\t\t\t\tisInsideAny = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isDenied) {\n\t\t\t\treturn {\n\t\t\t\t\toutcome: \"block\",\n\t\t\t\t\tgate: \"path_scope\",\n\t\t\t\t\treasonCode: \"path_denied\",\n\t\t\t\t\tmessage: `Path '${targetPath}' is explicitly denied by rule '${denyRule}'.`,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (!isInsideAny) {\n\t\t\t\t// Block only if the tool is mutating. Wait, read path outside allowed root -> block.\n\t\t\t\t// \"read path inside allowed root -> allow. write/edit path outside allowed root -> block. denied path inside allowed root -> block.\"\n\t\t\t\treturn {\n\t\t\t\t\toutcome: \"block\",\n\t\t\t\t\tgate: \"path_scope\",\n\t\t\t\t\treasonCode: \"path_outside_allowed_roots\",\n\t\t\t\t\tmessage: `Path '${targetPath}' is outside all allowed roots.`,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2.5. Capability checks\n\tif (!hasCapabilityPolicyForTool(input.toolName)) {\n\t\treturn {\n\t\t\toutcome: \"block\",\n\t\t\tgate: \"tool_gate\",\n\t\t\treasonCode: \"unknown_tool_capability\",\n\t\t\tmessage: `Tool '${input.toolName}' has no capability policy in the active envelope.`,\n\t\t};\n\t}\n\n\tconst requiredCaps = requiredCapabilitiesForTool(input.toolName, input.args);\n\tif (!hasRequiredCapabilityForTool(envelope.capabilities, input.toolName, input.args)) {\n\t\treturn {\n\t\t\toutcome: \"block\",\n\t\t\tgate: \"tool_gate\",\n\t\t\treasonCode: \"missing_capability\",\n\t\t\tmessage: `Tool '${input.toolName}' requires capability '${requiredCaps.join(\" or \")}', which is missing from the active envelope.`,\n\t\t};\n\t}\n\tlet command = \"\";\n\tif (\n\t\tinput.toolName === \"bash\" ||\n\t\tinput.toolName === \"powershell\" ||\n\t\tinput.toolName === \"shell\" ||\n\t\tinput.toolName === \"python\"\n\t) {\n\t\tconst argsObj = input.args as Record<string, unknown>;\n\t\tif (argsObj && typeof argsObj.command === \"string\") command = argsObj.command;\n\t\telse if (input.toolName === \"python\" && argsObj && typeof argsObj.code === \"string\") command = argsObj.code;\n\t\telse if (input.toolName === \"python\" && argsObj && typeof argsObj.scriptPath === \"string\") {\n\t\t\tcommand = `python ${argsObj.scriptPath}`;\n\t\t}\n\t}\n\n\tconst riskResult = assessOperationRisk({\n\t\toperation: `Tool ${input.toolName}`,\n\t\ttoolName: input.toolName,\n\t\tcommand,\n\t\tpaths,\n\t\tcapabilities: envelope.capabilities,\n\t});\n\n\tif (riskResult.requiresApproval) {\n\t\treturn {\n\t\t\toutcome: \"ask-user\", // or block, prompt says: ask-user/block\n\t\t\tgate: \"risk_assessment\",\n\t\t\treasonCode: riskResult.reasonCode,\n\t\t\tmessage: `Operation requires approval: ${riskResult.reasons.join(\", \")}`,\n\t\t};\n\t}\n\n\tif (riskResult.risk === \"high-impact\") {\n\t\treturn {\n\t\t\toutcome: \"ask-user\",\n\t\t\tgate: \"risk_assessment\",\n\t\t\treasonCode: riskResult.reasonCode,\n\t\t\tmessage: `High-impact operation requires review: ${riskResult.reasons.join(\", \")}`,\n\t\t};\n\t}\n\n\treturn {\n\t\toutcome: \"allow\",\n\t\tgate: \"tool_gate\",\n\t\treasonCode: \"allowed_by_envelope\",\n\t\tmessage: \"Operation allowed by current capability envelope.\",\n\t};\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function getPrivateLaneDeniedPaths(cwd: string, agentDir: string): string[];
2
+ //# sourceMappingURL=lane-private-paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lane-private-paths.d.ts","sourceRoot":"","sources":["../../../src/core/autonomy/lane-private-paths.ts"],"names":[],"mappings":"AAGA,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAYjF","sourcesContent":["import path from \"node:path\";\nimport { configFile, getWorkRoot, sessionsDir, stateDir } from \"../agent-paths.ts\";\n\nexport function getPrivateLaneDeniedPaths(cwd: string, agentDir: string): string[] {\n\treturn [\n\t\tconfigFile(agentDir, \"auth.json\"),\n\t\tconfigFile(agentDir, \"MEMORY.md\"),\n\t\tconfigFile(agentDir, \"USER.md\"),\n\t\tconfigFile(agentDir, \"settings.json\"),\n\t\tconfigFile(agentDir, \"models.json\"),\n\t\tsessionsDir(agentDir),\n\t\tstateDir(agentDir),\n\t\tgetWorkRoot(agentDir),\n\t\tpath.join(cwd, \".pi\", \"settings.json\"),\n\t];\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import path from "node:path";
2
+ import { configFile, getWorkRoot, sessionsDir, stateDir } from "../agent-paths.js";
3
+ export function getPrivateLaneDeniedPaths(cwd, agentDir) {
4
+ return [
5
+ configFile(agentDir, "auth.json"),
6
+ configFile(agentDir, "MEMORY.md"),
7
+ configFile(agentDir, "USER.md"),
8
+ configFile(agentDir, "settings.json"),
9
+ configFile(agentDir, "models.json"),
10
+ sessionsDir(agentDir),
11
+ stateDir(agentDir),
12
+ getWorkRoot(agentDir),
13
+ path.join(cwd, ".pi", "settings.json"),
14
+ ];
15
+ }
16
+ //# sourceMappingURL=lane-private-paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lane-private-paths.js","sourceRoot":"","sources":["../../../src/core/autonomy/lane-private-paths.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAEnF,MAAM,UAAU,yBAAyB,CAAC,GAAW,EAAE,QAAgB,EAAY;IAClF,OAAO;QACN,UAAU,CAAC,QAAQ,EAAE,WAAW,CAAC;QACjC,UAAU,CAAC,QAAQ,EAAE,WAAW,CAAC;QACjC,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC;QAC/B,UAAU,CAAC,QAAQ,EAAE,eAAe,CAAC;QACrC,UAAU,CAAC,QAAQ,EAAE,aAAa,CAAC;QACnC,WAAW,CAAC,QAAQ,CAAC;QACrB,QAAQ,CAAC,QAAQ,CAAC;QAClB,WAAW,CAAC,QAAQ,CAAC;QACrB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,eAAe,CAAC;KACtC,CAAC;AAAA,CACF","sourcesContent":["import path from \"node:path\";\nimport { configFile, getWorkRoot, sessionsDir, stateDir } from \"../agent-paths.ts\";\n\nexport function getPrivateLaneDeniedPaths(cwd: string, agentDir: string): string[] {\n\treturn [\n\t\tconfigFile(agentDir, \"auth.json\"),\n\t\tconfigFile(agentDir, \"MEMORY.md\"),\n\t\tconfigFile(agentDir, \"USER.md\"),\n\t\tconfigFile(agentDir, \"settings.json\"),\n\t\tconfigFile(agentDir, \"models.json\"),\n\t\tsessionsDir(agentDir),\n\t\tstateDir(agentDir),\n\t\tgetWorkRoot(agentDir),\n\t\tpath.join(cwd, \".pi\", \"settings.json\"),\n\t];\n}\n"]}
@@ -1,4 +1,6 @@
1
1
  import type { AgentLoopConfig, AgentTool } from "@caupulican/pi-agent-core";
2
+ import { CapabilityGateway } from "../orchestration/capability-gateway.ts";
3
+ import type { ExecutionGrant, OrchestrationExecutionPolicy, ToolCapabilityManifest } from "../orchestration/contracts.ts";
2
4
  import type { NormalizedProfile } from "../profile-registry.ts";
3
5
  export interface LaneToolSurface {
4
6
  /** Fresh tools owned by this lane only; no foreground tool instances or extension state leak in. */
@@ -11,6 +13,8 @@ export interface LaneToolSurface {
11
13
  unboundAllowPatterns: string[];
12
14
  /** Per-call path and capability gate for the isolated child loop. */
13
15
  beforeToolCall: NonNullable<AgentLoopConfig["beforeToolCall"]>;
16
+ /** Canonical cumulative authority/budget meter for a compiled worker grant. */
17
+ gateway?: CapabilityGateway;
14
18
  }
15
19
  export interface LaneToolSurfaceOptions {
16
20
  cwd: string;
@@ -22,6 +26,12 @@ export interface LaneToolSurfaceOptions {
22
26
  /** Research never sets this. Workers require both this flag and at least one write path. */
23
27
  writeEnabled?: boolean;
24
28
  writePaths?: readonly string[];
29
+ /** Present only for process-capable owner profiles; absent means no process tool is materialized. */
30
+ executionPolicy?: OrchestrationExecutionPolicy;
31
+ processMaxWallClockMs?: number;
32
+ /** Compiled policy path. When present, it is the only authorization source for this surface. */
33
+ grant?: ExecutionGrant;
34
+ toolManifests?: readonly ToolCapabilityManifest[];
25
35
  }
26
36
  /**
27
37
  * Materialize a fresh, fail-closed tool surface for one isolated lane.
@@ -1 +1 @@
1
- {"version":3,"file":"lane-tool-surface.d.ts","sourceRoot":"","sources":["../../../src/core/autonomy/lane-tool-surface.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAE5E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAoBhE,MAAM,WAAW,eAAe;IAC/B,oGAAoG;IACpG,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,8FAA8F;IAC9F,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,yEAAyE;IACzE,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,iGAAiG;IACjG,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,qEAAqE;IACrE,cAAc,EAAE,WAAW,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAC,CAAC;CAC/D;AAED,MAAM,WAAW,sBAAsB;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,yEAAyE;IACzE,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,wGAAwG;IACxG,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,4FAA4F;IAC5F,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B;AAsDD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,eAAe,CA0DtF","sourcesContent":["import path from \"node:path\";\nimport type { AgentLoopConfig, AgentTool } from \"@caupulican/pi-agent-core\";\nimport { type Static, Type } from \"typebox\";\nimport type { NormalizedProfile } from \"../profile-registry.ts\";\nimport { matchesResourceProfilePattern } from \"../settings-manager.ts\";\nimport { createEditTool } from \"../tools/edit.ts\";\nimport { createFindTool } from \"../tools/find.ts\";\nimport { createGrepTool } from \"../tools/grep.ts\";\nimport { createLsTool } from \"../tools/ls.ts\";\nimport { createReadTool } from \"../tools/read.ts\";\nimport { createWriteTool } from \"../tools/write.ts\";\nimport type { CapabilityEnvelope } from \"./contracts.ts\";\nimport { evaluateToolGate } from \"./gates.ts\";\n\nconst READ_ONLY_LANE_TOOL_NAMES = [\"read\", \"grep\", \"find\", \"ls\"] as const;\nconst MEMORY_LANE_TOOL_NAME = \"memory\" as const;\nconst WRITE_LANE_TOOL_NAMES = [\"write\", \"edit\"] as const;\nconst laneMemorySchema = Type.Object({\n\tquery: Type.String({ description: \"What relevant standing memory or prior evidence to retrieve\" }),\n});\ntype LaneMemoryParams = Static<typeof laneMemorySchema>;\nconst WRITE_LANE_TOOL_NAME_SET = new Set<string>(WRITE_LANE_TOOL_NAMES);\n\nexport interface LaneToolSurface {\n\t/** Fresh tools owned by this lane only; no foreground tool instances or extension state leak in. */\n\ttools: AgentTool[];\n\t/** Exact names after profile globs are expanded. Safe to persist in a capability envelope. */\n\tallowedTools: string[];\n\t/** Exact safe-candidate names denied by the profile's block patterns. */\n\tdeniedTools: string[];\n\t/** Explicit grants that bind to no classified lane candidate (opaque tools stay fail-closed). */\n\tunboundAllowPatterns: string[];\n\t/** Per-call path and capability gate for the isolated child loop. */\n\tbeforeToolCall: NonNullable<AgentLoopConfig[\"beforeToolCall\"]>;\n}\n\nexport interface LaneToolSurfaceOptions {\n\tcwd: string;\n\tprofile?: NormalizedProfile;\n\t/** Private harness state that generic file tools must never traverse. */\n\tdeniedPaths?: readonly string[];\n\t/** Orchestrator-requested, policy-filtered read-only memory retrieval. Omitted means no memory tool. */\n\treadMemory?: (query: string) => Promise<string>;\n\t/** Research never sets this. Workers require both this flag and at least one write path. */\n\twriteEnabled?: boolean;\n\twritePaths?: readonly string[];\n}\n\nfunction strictLaneProfilePatterns(profile: NormalizedProfile | undefined): {\n\tallow: string[];\n\tblock: string[];\n} {\n\tif (!profile) return { allow: [], block: [] };\n\tconst filter = profile.resources.tools;\n\tconst allow = [...(filter?.allow ?? [])];\n\tconst block = [...(filter?.block ?? [])];\n\t// Strict UAC: a shipped profile is the complete authority grant. Grant-all must be explicit.\n\tif (allow.length === 0 && block.length === 0) return { allow: [], block: [\"*\"] };\n\treturn { allow, block };\n}\n\nfunction resolveWriteRoots(cwd: string, writePaths: readonly string[]): string[] {\n\treturn writePaths.map((entry) => (path.isAbsolute(entry) ? path.resolve(entry) : path.resolve(cwd, entry)));\n}\n\nfunction createLaneTools(\n\tcwd: string,\n\tnames: readonly string[],\n\treadMemory?: (query: string) => Promise<string>,\n): AgentTool[] {\n\tconst factories = new Map<string, () => AgentTool>([\n\t\t[\"read\", () => createReadTool(cwd)],\n\t\t[\"grep\", () => createGrepTool(cwd)],\n\t\t[\"find\", () => createFindTool(cwd)],\n\t\t[\"ls\", () => createLsTool(cwd)],\n\t\t[\"write\", () => createWriteTool(cwd)],\n\t\t[\"edit\", () => createEditTool(cwd)],\n\t]);\n\tif (readMemory) {\n\t\tfactories.set(MEMORY_LANE_TOOL_NAME, () => ({\n\t\t\tname: MEMORY_LANE_TOOL_NAME,\n\t\t\tlabel: \"Read Memory\",\n\t\t\tdescription:\n\t\t\t\t\"Retrieve bounded, source-labeled standing memory relevant to this delegated task. Read-only: no memory writes or lifecycle actions are available.\",\n\t\t\tparameters: laneMemorySchema,\n\t\t\texecute: async (_toolCallId, params) => {\n\t\t\t\tconst { query } = params as LaneMemoryParams;\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\" as const, text: await readMemory(query) }],\n\t\t\t\t\tdetails: { readOnly: true },\n\t\t\t\t};\n\t\t\t},\n\t\t}));\n\t}\n\treturn names.flatMap((name) => {\n\t\tconst factory = factories.get(name);\n\t\treturn factory ? [factory()] : [];\n\t});\n}\n\n/**\n * Materialize a fresh, fail-closed tool surface for one isolated lane.\n *\n * Profiles select only from classified built-ins. Opaque extension tools, shell, memory, goals,\n * and `delegate` are never candidates, so a wildcard cannot manufacture unknown authority or\n * recursively spawn more workers. Write/edit additionally require the explicit worker write switch\n * and a non-empty path scope; research therefore stays read-only regardless of profile contents.\n */\nexport function createLaneToolSurface(options: LaneToolSurfaceOptions): LaneToolSurface {\n\tconst writeCapable = options.writeEnabled === true && (options.writePaths?.length ?? 0) > 0;\n\tconst candidateNames = [\n\t\t...READ_ONLY_LANE_TOOL_NAMES,\n\t\t...(options.readMemory ? [MEMORY_LANE_TOOL_NAME] : []),\n\t\t...(writeCapable ? WRITE_LANE_TOOL_NAMES : []),\n\t];\n\tconst patterns = strictLaneProfilePatterns(options.profile);\n\tconst deniedTools = candidateNames.filter((name) => matchesResourceProfilePattern(name, patterns.block));\n\tconst unboundAllowPatterns = patterns.allow.filter(\n\t\t(pattern) => !candidateNames.some((name) => matchesResourceProfilePattern(name, [pattern])),\n\t);\n\tconst allowedTools = candidateNames.filter(\n\t\t(name) =>\n\t\t\t(patterns.allow.length === 0 || matchesResourceProfilePattern(name, patterns.allow)) &&\n\t\t\t!matchesResourceProfilePattern(name, patterns.block),\n\t);\n\tconst allowedToolSet = new Set<string>(allowedTools);\n\tconst deniedPaths = options.deniedPaths?.map((entry) => path.resolve(entry));\n\tconst readEnvelope: CapabilityEnvelope = {\n\t\tid: \"isolated-lane-read-tools\",\n\t\tcapabilities: [\"read_files\", ...(allowedToolSet.has(MEMORY_LANE_TOOL_NAME) ? ([\"memory_read\"] as const) : [])],\n\t\tallowedTools,\n\t\tdeniedTools,\n\t\tallowedPaths: [path.resolve(options.cwd)],\n\t\t...(deniedPaths && deniedPaths.length > 0 ? { deniedPaths } : {}),\n\t};\n\tconst writeEnvelope: CapabilityEnvelope = {\n\t\tid: \"isolated-lane-write-tools\",\n\t\tcapabilities: [\"write_files\"],\n\t\tallowedTools,\n\t\tdeniedTools,\n\t\tallowedPaths: resolveWriteRoots(options.cwd, options.writePaths ?? []),\n\t\t...(deniedPaths && deniedPaths.length > 0 ? { deniedPaths } : {}),\n\t};\n\n\treturn {\n\t\ttools: createLaneTools(options.cwd, allowedTools, options.readMemory),\n\t\tallowedTools,\n\t\tdeniedTools,\n\t\tunboundAllowPatterns,\n\t\tbeforeToolCall: async ({ toolCall, args }) => {\n\t\t\tif (!allowedToolSet.has(toolCall.name)) {\n\t\t\t\treturn { block: true, reason: `Lane tool '${toolCall.name}' is outside the materialized UAC surface.` };\n\t\t\t}\n\t\t\tconst outcome = evaluateToolGate({\n\t\t\t\ttoolName: toolCall.name,\n\t\t\t\targs,\n\t\t\t\tcwd: options.cwd,\n\t\t\t\tenvelope: WRITE_LANE_TOOL_NAME_SET.has(toolCall.name) ? writeEnvelope : readEnvelope,\n\t\t\t});\n\t\t\tif (outcome.outcome === \"allow\") return undefined;\n\t\t\treturn {\n\t\t\t\tblock: true,\n\t\t\t\treason: `Lane tool blocked (${outcome.reasonCode}): ${outcome.message ?? \"capability gate denied it\"}`,\n\t\t\t};\n\t\t},\n\t};\n}\n"]}
1
+ {"version":3,"file":"lane-tool-surface.d.ts","sourceRoot":"","sources":["../../../src/core/autonomy/lane-tool-surface.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAE5E,OAAO,EAAE,iBAAiB,EAAgC,MAAM,wCAAwC,CAAC;AACzG,OAAO,KAAK,EACX,cAAc,EACd,4BAA4B,EAC5B,sBAAsB,EACtB,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAsBhE,MAAM,WAAW,eAAe;IAC/B,oGAAoG;IACpG,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,8FAA8F;IAC9F,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,yEAAyE;IACzE,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,iGAAiG;IACjG,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,qEAAqE;IACrE,cAAc,EAAE,WAAW,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC/D,+EAA+E;IAC/E,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,yEAAyE;IACzE,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,wGAAwG;IACxG,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,4FAA4F;IAC5F,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,qGAAqG;IACrG,eAAe,CAAC,EAAE,4BAA4B,CAAC;IAC/C,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,gGAAgG;IAChG,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,aAAa,CAAC,EAAE,SAAS,sBAAsB,EAAE,CAAC;CAClD;AA6DD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,eAAe,CAiGtF","sourcesContent":["import path from \"node:path\";\nimport type { AgentLoopConfig, AgentTool } from \"@caupulican/pi-agent-core\";\nimport { type Static, Type } from \"typebox\";\nimport { CapabilityGateway, CapabilityGatewayDeniedError } from \"../orchestration/capability-gateway.ts\";\nimport type {\n\tExecutionGrant,\n\tOrchestrationExecutionPolicy,\n\tToolCapabilityManifest,\n} from \"../orchestration/contracts.ts\";\nimport type { NormalizedProfile } from \"../profile-registry.ts\";\nimport { matchesResourceProfilePattern } from \"../settings-manager.ts\";\nimport { createEditTool } from \"../tools/edit.ts\";\nimport { createFindTool } from \"../tools/find.ts\";\nimport { createGrepTool } from \"../tools/grep.ts\";\nimport { createLsTool } from \"../tools/ls.ts\";\nimport { createReadTool } from \"../tools/read.ts\";\nimport { createRunProcessTool } from \"../tools/run-process.ts\";\nimport { createWriteTool } from \"../tools/write.ts\";\nimport type { CapabilityEnvelope } from \"./contracts.ts\";\nimport { evaluateToolGate } from \"./gates.ts\";\n\nconst READ_ONLY_LANE_TOOL_NAMES = [\"read\", \"grep\", \"find\", \"ls\"] as const;\nconst MEMORY_LANE_TOOL_NAME = \"memory\" as const;\nconst WRITE_LANE_TOOL_NAMES = [\"write\", \"edit\"] as const;\nconst PROCESS_LANE_TOOL_NAME = \"run_process\" as const;\nconst laneMemorySchema = Type.Object({\n\tquery: Type.String({ description: \"What relevant standing memory or prior evidence to retrieve\" }),\n});\ntype LaneMemoryParams = Static<typeof laneMemorySchema>;\nconst WRITE_LANE_TOOL_NAME_SET = new Set<string>(WRITE_LANE_TOOL_NAMES);\n\nexport interface LaneToolSurface {\n\t/** Fresh tools owned by this lane only; no foreground tool instances or extension state leak in. */\n\ttools: AgentTool[];\n\t/** Exact names after profile globs are expanded. Safe to persist in a capability envelope. */\n\tallowedTools: string[];\n\t/** Exact safe-candidate names denied by the profile's block patterns. */\n\tdeniedTools: string[];\n\t/** Explicit grants that bind to no classified lane candidate (opaque tools stay fail-closed). */\n\tunboundAllowPatterns: string[];\n\t/** Per-call path and capability gate for the isolated child loop. */\n\tbeforeToolCall: NonNullable<AgentLoopConfig[\"beforeToolCall\"]>;\n\t/** Canonical cumulative authority/budget meter for a compiled worker grant. */\n\tgateway?: CapabilityGateway;\n}\n\nexport interface LaneToolSurfaceOptions {\n\tcwd: string;\n\tprofile?: NormalizedProfile;\n\t/** Private harness state that generic file tools must never traverse. */\n\tdeniedPaths?: readonly string[];\n\t/** Orchestrator-requested, policy-filtered read-only memory retrieval. Omitted means no memory tool. */\n\treadMemory?: (query: string) => Promise<string>;\n\t/** Research never sets this. Workers require both this flag and at least one write path. */\n\twriteEnabled?: boolean;\n\twritePaths?: readonly string[];\n\t/** Present only for process-capable owner profiles; absent means no process tool is materialized. */\n\texecutionPolicy?: OrchestrationExecutionPolicy;\n\tprocessMaxWallClockMs?: number;\n\t/** Compiled policy path. When present, it is the only authorization source for this surface. */\n\tgrant?: ExecutionGrant;\n\ttoolManifests?: readonly ToolCapabilityManifest[];\n}\n\nfunction strictLaneProfilePatterns(profile: NormalizedProfile | undefined): {\n\tallow: string[];\n\tblock: string[];\n} {\n\tif (!profile) return { allow: [], block: [] };\n\tconst filter = profile.resources.tools;\n\tconst allow = [...(filter?.allow ?? [])];\n\tconst block = [...(filter?.block ?? [])];\n\t// Strict UAC: a shipped profile is the complete authority grant. Grant-all must be explicit.\n\tif (allow.length === 0 && block.length === 0) return { allow: [], block: [\"*\"] };\n\treturn { allow, block };\n}\n\nfunction resolveWriteRoots(cwd: string, writePaths: readonly string[]): string[] {\n\treturn writePaths.map((entry) => (path.isAbsolute(entry) ? path.resolve(entry) : path.resolve(cwd, entry)));\n}\n\nfunction createLaneTools(\n\tcwd: string,\n\tnames: readonly string[],\n\treadMemory?: (query: string) => Promise<string>,\n\texecutionPolicy?: OrchestrationExecutionPolicy,\n\tprocessMaxWallClockMs = 0,\n): AgentTool[] {\n\tconst factories = new Map<string, () => AgentTool>([\n\t\t[\"read\", () => createReadTool(cwd)],\n\t\t[\"grep\", () => createGrepTool(cwd)],\n\t\t[\"find\", () => createFindTool(cwd)],\n\t\t[\"ls\", () => createLsTool(cwd)],\n\t\t[\"write\", () => createWriteTool(cwd)],\n\t\t[\"edit\", () => createEditTool(cwd)],\n\t]);\n\tif (executionPolicy) {\n\t\tfactories.set(PROCESS_LANE_TOOL_NAME, () =>\n\t\t\tcreateRunProcessTool(cwd, { policy: executionPolicy, maxWallClockMs: processMaxWallClockMs }),\n\t\t);\n\t}\n\tif (readMemory) {\n\t\tfactories.set(MEMORY_LANE_TOOL_NAME, () => ({\n\t\t\tname: MEMORY_LANE_TOOL_NAME,\n\t\t\tlabel: \"Read Memory\",\n\t\t\tdescription:\n\t\t\t\t\"Retrieve bounded, source-labeled standing memory relevant to this delegated task. Read-only: no memory writes or lifecycle actions are available.\",\n\t\t\tparameters: laneMemorySchema,\n\t\t\texecute: async (_toolCallId, params) => {\n\t\t\t\tconst { query } = params as LaneMemoryParams;\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\" as const, text: await readMemory(query) }],\n\t\t\t\t\tdetails: { readOnly: true },\n\t\t\t\t};\n\t\t\t},\n\t\t}));\n\t}\n\treturn names.flatMap((name) => {\n\t\tconst factory = factories.get(name);\n\t\treturn factory ? [factory()] : [];\n\t});\n}\n\n/**\n * Materialize a fresh, fail-closed tool surface for one isolated lane.\n *\n * Profiles select only from classified built-ins. Opaque extension tools, shell, memory, goals,\n * and `delegate` are never candidates, so a wildcard cannot manufacture unknown authority or\n * recursively spawn more workers. Write/edit additionally require the explicit worker write switch\n * and a non-empty path scope; research therefore stays read-only regardless of profile contents.\n */\nexport function createLaneToolSurface(options: LaneToolSurfaceOptions): LaneToolSurface {\n\tconst writeCapable = options.writeEnabled === true && (options.writePaths?.length ?? 0) > 0;\n\tconst candidateNames = [\n\t\t...READ_ONLY_LANE_TOOL_NAMES,\n\t\t...(options.readMemory ? [MEMORY_LANE_TOOL_NAME] : []),\n\t\t...(writeCapable ? WRITE_LANE_TOOL_NAMES : []),\n\t\t...(options.executionPolicy ? [PROCESS_LANE_TOOL_NAME] : []),\n\t];\n\tconst patterns = strictLaneProfilePatterns(options.profile);\n\tconst compiledToolNames = new Set(options.grant?.allowedTools ?? []);\n\tconst deniedTools = candidateNames.filter((name) =>\n\t\toptions.grant ? !compiledToolNames.has(name) : matchesResourceProfilePattern(name, patterns.block),\n\t);\n\tconst unboundAllowPatterns = options.grant\n\t\t? []\n\t\t: patterns.allow.filter(\n\t\t\t\t(pattern) => !candidateNames.some((name) => matchesResourceProfilePattern(name, [pattern])),\n\t\t\t);\n\tconst allowedTools = options.grant\n\t\t? candidateNames.filter((name) => compiledToolNames.has(name))\n\t\t: candidateNames.filter(\n\t\t\t\t(name) =>\n\t\t\t\t\t(patterns.allow.length === 0 || matchesResourceProfilePattern(name, patterns.allow)) &&\n\t\t\t\t\t!matchesResourceProfilePattern(name, patterns.block),\n\t\t\t);\n\tconst allowedToolSet = new Set<string>(allowedTools);\n\tconst manifestsByName = new Map(options.toolManifests?.map((manifest) => [manifest.toolName, manifest]) ?? []);\n\tif (options.grant?.allowedTools.some((name) => !manifestsByName.has(name))) {\n\t\tthrow new Error(\"Compiled lane grant references a tool without a capability manifest.\");\n\t}\n\tconst gateway = options.grant ? new CapabilityGateway({ grant: options.grant, cwd: options.cwd }) : undefined;\n\tconst deniedPaths = options.deniedPaths?.map((entry) => path.resolve(entry));\n\tconst readEnvelope: CapabilityEnvelope = {\n\t\tid: \"isolated-lane-read-tools\",\n\t\tcapabilities: [\n\t\t\t\"filesystem.read\",\n\t\t\t...(allowedToolSet.has(MEMORY_LANE_TOOL_NAME) ? ([\"memory.query\"] as const) : []),\n\t\t\t...(allowedToolSet.has(PROCESS_LANE_TOOL_NAME) ? ([\"process.exec\"] as const) : []),\n\t\t],\n\t\tallowedTools,\n\t\tdeniedTools,\n\t\tallowedPaths: [path.resolve(options.cwd)],\n\t\t...(deniedPaths && deniedPaths.length > 0 ? { deniedPaths } : {}),\n\t};\n\tconst writeEnvelope: CapabilityEnvelope = {\n\t\tid: \"isolated-lane-write-tools\",\n\t\tcapabilities: [\"filesystem.write\"],\n\t\tallowedTools,\n\t\tdeniedTools,\n\t\tallowedPaths: resolveWriteRoots(options.cwd, options.writePaths ?? []),\n\t\t...(deniedPaths && deniedPaths.length > 0 ? { deniedPaths } : {}),\n\t};\n\n\treturn {\n\t\ttools: createLaneTools(\n\t\t\toptions.cwd,\n\t\t\tallowedTools,\n\t\t\toptions.readMemory,\n\t\t\toptions.executionPolicy,\n\t\t\toptions.processMaxWallClockMs,\n\t\t),\n\t\tallowedTools,\n\t\tdeniedTools,\n\t\tunboundAllowPatterns,\n\t\tbeforeToolCall: async ({ toolCall, args }) => {\n\t\t\tif (!allowedToolSet.has(toolCall.name)) {\n\t\t\t\treturn { block: true, reason: `Lane tool '${toolCall.name}' is outside the materialized UAC surface.` };\n\t\t\t}\n\t\t\tif (gateway) {\n\t\t\t\tconst manifest = manifestsByName.get(toolCall.name);\n\t\t\t\tif (!manifest) {\n\t\t\t\t\treturn { block: true, reason: `Lane tool '${toolCall.name}' has no compiled capability manifest.` };\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tgateway.authorizeToolCall(manifest, toolCall.name, args);\n\t\t\t\t\treturn undefined;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof CapabilityGatewayDeniedError) {\n\t\t\t\t\t\treturn { block: true, reason: `Lane tool blocked (${error.reasonCode}): ${error.message}` };\n\t\t\t\t\t}\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst outcome = evaluateToolGate({\n\t\t\t\ttoolName: toolCall.name,\n\t\t\t\targs,\n\t\t\t\tcwd: options.cwd,\n\t\t\t\tenvelope: WRITE_LANE_TOOL_NAME_SET.has(toolCall.name) ? writeEnvelope : readEnvelope,\n\t\t\t});\n\t\t\tif (outcome.outcome === \"allow\") return undefined;\n\t\t\treturn {\n\t\t\t\tblock: true,\n\t\t\t\treason: `Lane tool blocked (${outcome.reasonCode}): ${outcome.message ?? \"capability gate denied it\"}`,\n\t\t\t};\n\t\t},\n\t\t...(gateway ? { gateway } : {}),\n\t};\n}\n"]}
@@ -1,16 +1,19 @@
1
1
  import path from "node:path";
2
2
  import { Type } from "typebox";
3
+ import { CapabilityGateway, CapabilityGatewayDeniedError } from "../orchestration/capability-gateway.js";
3
4
  import { matchesResourceProfilePattern } from "../settings-manager.js";
4
5
  import { createEditTool } from "../tools/edit.js";
5
6
  import { createFindTool } from "../tools/find.js";
6
7
  import { createGrepTool } from "../tools/grep.js";
7
8
  import { createLsTool } from "../tools/ls.js";
8
9
  import { createReadTool } from "../tools/read.js";
10
+ import { createRunProcessTool } from "../tools/run-process.js";
9
11
  import { createWriteTool } from "../tools/write.js";
10
12
  import { evaluateToolGate } from "./gates.js";
11
13
  const READ_ONLY_LANE_TOOL_NAMES = ["read", "grep", "find", "ls"];
12
14
  const MEMORY_LANE_TOOL_NAME = "memory";
13
15
  const WRITE_LANE_TOOL_NAMES = ["write", "edit"];
16
+ const PROCESS_LANE_TOOL_NAME = "run_process";
14
17
  const laneMemorySchema = Type.Object({
15
18
  query: Type.String({ description: "What relevant standing memory or prior evidence to retrieve" }),
16
19
  });
@@ -29,7 +32,7 @@ function strictLaneProfilePatterns(profile) {
29
32
  function resolveWriteRoots(cwd, writePaths) {
30
33
  return writePaths.map((entry) => (path.isAbsolute(entry) ? path.resolve(entry) : path.resolve(cwd, entry)));
31
34
  }
32
- function createLaneTools(cwd, names, readMemory) {
35
+ function createLaneTools(cwd, names, readMemory, executionPolicy, processMaxWallClockMs = 0) {
33
36
  const factories = new Map([
34
37
  ["read", () => createReadTool(cwd)],
35
38
  ["grep", () => createGrepTool(cwd)],
@@ -38,6 +41,9 @@ function createLaneTools(cwd, names, readMemory) {
38
41
  ["write", () => createWriteTool(cwd)],
39
42
  ["edit", () => createEditTool(cwd)],
40
43
  ]);
44
+ if (executionPolicy) {
45
+ factories.set(PROCESS_LANE_TOOL_NAME, () => createRunProcessTool(cwd, { policy: executionPolicy, maxWallClockMs: processMaxWallClockMs }));
46
+ }
41
47
  if (readMemory) {
42
48
  factories.set(MEMORY_LANE_TOOL_NAME, () => ({
43
49
  name: MEMORY_LANE_TOOL_NAME,
@@ -72,17 +78,32 @@ export function createLaneToolSurface(options) {
72
78
  ...READ_ONLY_LANE_TOOL_NAMES,
73
79
  ...(options.readMemory ? [MEMORY_LANE_TOOL_NAME] : []),
74
80
  ...(writeCapable ? WRITE_LANE_TOOL_NAMES : []),
81
+ ...(options.executionPolicy ? [PROCESS_LANE_TOOL_NAME] : []),
75
82
  ];
76
83
  const patterns = strictLaneProfilePatterns(options.profile);
77
- const deniedTools = candidateNames.filter((name) => matchesResourceProfilePattern(name, patterns.block));
78
- const unboundAllowPatterns = patterns.allow.filter((pattern) => !candidateNames.some((name) => matchesResourceProfilePattern(name, [pattern])));
79
- const allowedTools = candidateNames.filter((name) => (patterns.allow.length === 0 || matchesResourceProfilePattern(name, patterns.allow)) &&
80
- !matchesResourceProfilePattern(name, patterns.block));
84
+ const compiledToolNames = new Set(options.grant?.allowedTools ?? []);
85
+ const deniedTools = candidateNames.filter((name) => options.grant ? !compiledToolNames.has(name) : matchesResourceProfilePattern(name, patterns.block));
86
+ const unboundAllowPatterns = options.grant
87
+ ? []
88
+ : patterns.allow.filter((pattern) => !candidateNames.some((name) => matchesResourceProfilePattern(name, [pattern])));
89
+ const allowedTools = options.grant
90
+ ? candidateNames.filter((name) => compiledToolNames.has(name))
91
+ : candidateNames.filter((name) => (patterns.allow.length === 0 || matchesResourceProfilePattern(name, patterns.allow)) &&
92
+ !matchesResourceProfilePattern(name, patterns.block));
81
93
  const allowedToolSet = new Set(allowedTools);
94
+ const manifestsByName = new Map(options.toolManifests?.map((manifest) => [manifest.toolName, manifest]) ?? []);
95
+ if (options.grant?.allowedTools.some((name) => !manifestsByName.has(name))) {
96
+ throw new Error("Compiled lane grant references a tool without a capability manifest.");
97
+ }
98
+ const gateway = options.grant ? new CapabilityGateway({ grant: options.grant, cwd: options.cwd }) : undefined;
82
99
  const deniedPaths = options.deniedPaths?.map((entry) => path.resolve(entry));
83
100
  const readEnvelope = {
84
101
  id: "isolated-lane-read-tools",
85
- capabilities: ["read_files", ...(allowedToolSet.has(MEMORY_LANE_TOOL_NAME) ? ["memory_read"] : [])],
102
+ capabilities: [
103
+ "filesystem.read",
104
+ ...(allowedToolSet.has(MEMORY_LANE_TOOL_NAME) ? ["memory.query"] : []),
105
+ ...(allowedToolSet.has(PROCESS_LANE_TOOL_NAME) ? ["process.exec"] : []),
106
+ ],
86
107
  allowedTools,
87
108
  deniedTools,
88
109
  allowedPaths: [path.resolve(options.cwd)],
@@ -90,14 +111,14 @@ export function createLaneToolSurface(options) {
90
111
  };
91
112
  const writeEnvelope = {
92
113
  id: "isolated-lane-write-tools",
93
- capabilities: ["write_files"],
114
+ capabilities: ["filesystem.write"],
94
115
  allowedTools,
95
116
  deniedTools,
96
117
  allowedPaths: resolveWriteRoots(options.cwd, options.writePaths ?? []),
97
118
  ...(deniedPaths && deniedPaths.length > 0 ? { deniedPaths } : {}),
98
119
  };
99
120
  return {
100
- tools: createLaneTools(options.cwd, allowedTools, options.readMemory),
121
+ tools: createLaneTools(options.cwd, allowedTools, options.readMemory, options.executionPolicy, options.processMaxWallClockMs),
101
122
  allowedTools,
102
123
  deniedTools,
103
124
  unboundAllowPatterns,
@@ -105,6 +126,22 @@ export function createLaneToolSurface(options) {
105
126
  if (!allowedToolSet.has(toolCall.name)) {
106
127
  return { block: true, reason: `Lane tool '${toolCall.name}' is outside the materialized UAC surface.` };
107
128
  }
129
+ if (gateway) {
130
+ const manifest = manifestsByName.get(toolCall.name);
131
+ if (!manifest) {
132
+ return { block: true, reason: `Lane tool '${toolCall.name}' has no compiled capability manifest.` };
133
+ }
134
+ try {
135
+ gateway.authorizeToolCall(manifest, toolCall.name, args);
136
+ return undefined;
137
+ }
138
+ catch (error) {
139
+ if (error instanceof CapabilityGatewayDeniedError) {
140
+ return { block: true, reason: `Lane tool blocked (${error.reasonCode}): ${error.message}` };
141
+ }
142
+ throw error;
143
+ }
144
+ }
108
145
  const outcome = evaluateToolGate({
109
146
  toolName: toolCall.name,
110
147
  args,
@@ -118,6 +155,7 @@ export function createLaneToolSurface(options) {
118
155
  reason: `Lane tool blocked (${outcome.reasonCode}): ${outcome.message ?? "capability gate denied it"}`,
119
156
  };
120
157
  },
158
+ ...(gateway ? { gateway } : {}),
121
159
  };
122
160
  }
123
161
  //# sourceMappingURL=lane-tool-surface.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lane-tool-surface.js","sourceRoot":"","sources":["../../../src/core/autonomy/lane-tool-surface.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\nimport type { AgentLoopConfig, AgentTool } from \"@caupulican/pi-agent-core\";\nimport { type Static, Type } from \"typebox\";\nimport type { NormalizedProfile } from \"../profile-registry.ts\";\nimport { matchesResourceProfilePattern } from \"../settings-manager.ts\";\nimport { createEditTool } from \"../tools/edit.ts\";\nimport { createFindTool } from \"../tools/find.ts\";\nimport { createGrepTool } from \"../tools/grep.ts\";\nimport { createLsTool } from \"../tools/ls.ts\";\nimport { createReadTool } from \"../tools/read.ts\";\nimport { createWriteTool } from \"../tools/write.ts\";\nimport type { CapabilityEnvelope } from \"./contracts.ts\";\nimport { evaluateToolGate } from \"./gates.ts\";\n\nconst READ_ONLY_LANE_TOOL_NAMES = [\"read\", \"grep\", \"find\", \"ls\"] as const;\nconst MEMORY_LANE_TOOL_NAME = \"memory\" as const;\nconst WRITE_LANE_TOOL_NAMES = [\"write\", \"edit\"] as const;\nconst laneMemorySchema = Type.Object({\n\tquery: Type.String({ description: \"What relevant standing memory or prior evidence to retrieve\" }),\n});\ntype LaneMemoryParams = Static<typeof laneMemorySchema>;\nconst WRITE_LANE_TOOL_NAME_SET = new Set<string>(WRITE_LANE_TOOL_NAMES);\n\nexport interface LaneToolSurface {\n\t/** Fresh tools owned by this lane only; no foreground tool instances or extension state leak in. */\n\ttools: AgentTool[];\n\t/** Exact names after profile globs are expanded. Safe to persist in a capability envelope. */\n\tallowedTools: string[];\n\t/** Exact safe-candidate names denied by the profile's block patterns. */\n\tdeniedTools: string[];\n\t/** Explicit grants that bind to no classified lane candidate (opaque tools stay fail-closed). */\n\tunboundAllowPatterns: string[];\n\t/** Per-call path and capability gate for the isolated child loop. */\n\tbeforeToolCall: NonNullable<AgentLoopConfig[\"beforeToolCall\"]>;\n}\n\nexport interface LaneToolSurfaceOptions {\n\tcwd: string;\n\tprofile?: NormalizedProfile;\n\t/** Private harness state that generic file tools must never traverse. */\n\tdeniedPaths?: readonly string[];\n\t/** Orchestrator-requested, policy-filtered read-only memory retrieval. Omitted means no memory tool. */\n\treadMemory?: (query: string) => Promise<string>;\n\t/** Research never sets this. Workers require both this flag and at least one write path. */\n\twriteEnabled?: boolean;\n\twritePaths?: readonly string[];\n}\n\nfunction strictLaneProfilePatterns(profile: NormalizedProfile | undefined): {\n\tallow: string[];\n\tblock: string[];\n} {\n\tif (!profile) return { allow: [], block: [] };\n\tconst filter = profile.resources.tools;\n\tconst allow = [...(filter?.allow ?? [])];\n\tconst block = [...(filter?.block ?? [])];\n\t// Strict UAC: a shipped profile is the complete authority grant. Grant-all must be explicit.\n\tif (allow.length === 0 && block.length === 0) return { allow: [], block: [\"*\"] };\n\treturn { allow, block };\n}\n\nfunction resolveWriteRoots(cwd: string, writePaths: readonly string[]): string[] {\n\treturn writePaths.map((entry) => (path.isAbsolute(entry) ? path.resolve(entry) : path.resolve(cwd, entry)));\n}\n\nfunction createLaneTools(\n\tcwd: string,\n\tnames: readonly string[],\n\treadMemory?: (query: string) => Promise<string>,\n): AgentTool[] {\n\tconst factories = new Map<string, () => AgentTool>([\n\t\t[\"read\", () => createReadTool(cwd)],\n\t\t[\"grep\", () => createGrepTool(cwd)],\n\t\t[\"find\", () => createFindTool(cwd)],\n\t\t[\"ls\", () => createLsTool(cwd)],\n\t\t[\"write\", () => createWriteTool(cwd)],\n\t\t[\"edit\", () => createEditTool(cwd)],\n\t]);\n\tif (readMemory) {\n\t\tfactories.set(MEMORY_LANE_TOOL_NAME, () => ({\n\t\t\tname: MEMORY_LANE_TOOL_NAME,\n\t\t\tlabel: \"Read Memory\",\n\t\t\tdescription:\n\t\t\t\t\"Retrieve bounded, source-labeled standing memory relevant to this delegated task. Read-only: no memory writes or lifecycle actions are available.\",\n\t\t\tparameters: laneMemorySchema,\n\t\t\texecute: async (_toolCallId, params) => {\n\t\t\t\tconst { query } = params as LaneMemoryParams;\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\" as const, text: await readMemory(query) }],\n\t\t\t\t\tdetails: { readOnly: true },\n\t\t\t\t};\n\t\t\t},\n\t\t}));\n\t}\n\treturn names.flatMap((name) => {\n\t\tconst factory = factories.get(name);\n\t\treturn factory ? [factory()] : [];\n\t});\n}\n\n/**\n * Materialize a fresh, fail-closed tool surface for one isolated lane.\n *\n * Profiles select only from classified built-ins. Opaque extension tools, shell, memory, goals,\n * and `delegate` are never candidates, so a wildcard cannot manufacture unknown authority or\n * recursively spawn more workers. Write/edit additionally require the explicit worker write switch\n * and a non-empty path scope; research therefore stays read-only regardless of profile contents.\n */\nexport function createLaneToolSurface(options: LaneToolSurfaceOptions): LaneToolSurface {\n\tconst writeCapable = options.writeEnabled === true && (options.writePaths?.length ?? 0) > 0;\n\tconst candidateNames = [\n\t\t...READ_ONLY_LANE_TOOL_NAMES,\n\t\t...(options.readMemory ? [MEMORY_LANE_TOOL_NAME] : []),\n\t\t...(writeCapable ? WRITE_LANE_TOOL_NAMES : []),\n\t];\n\tconst patterns = strictLaneProfilePatterns(options.profile);\n\tconst deniedTools = candidateNames.filter((name) => matchesResourceProfilePattern(name, patterns.block));\n\tconst unboundAllowPatterns = patterns.allow.filter(\n\t\t(pattern) => !candidateNames.some((name) => matchesResourceProfilePattern(name, [pattern])),\n\t);\n\tconst allowedTools = candidateNames.filter(\n\t\t(name) =>\n\t\t\t(patterns.allow.length === 0 || matchesResourceProfilePattern(name, patterns.allow)) &&\n\t\t\t!matchesResourceProfilePattern(name, patterns.block),\n\t);\n\tconst allowedToolSet = new Set<string>(allowedTools);\n\tconst deniedPaths = options.deniedPaths?.map((entry) => path.resolve(entry));\n\tconst readEnvelope: CapabilityEnvelope = {\n\t\tid: \"isolated-lane-read-tools\",\n\t\tcapabilities: [\"read_files\", ...(allowedToolSet.has(MEMORY_LANE_TOOL_NAME) ? ([\"memory_read\"] as const) : [])],\n\t\tallowedTools,\n\t\tdeniedTools,\n\t\tallowedPaths: [path.resolve(options.cwd)],\n\t\t...(deniedPaths && deniedPaths.length > 0 ? { deniedPaths } : {}),\n\t};\n\tconst writeEnvelope: CapabilityEnvelope = {\n\t\tid: \"isolated-lane-write-tools\",\n\t\tcapabilities: [\"write_files\"],\n\t\tallowedTools,\n\t\tdeniedTools,\n\t\tallowedPaths: resolveWriteRoots(options.cwd, options.writePaths ?? []),\n\t\t...(deniedPaths && deniedPaths.length > 0 ? { deniedPaths } : {}),\n\t};\n\n\treturn {\n\t\ttools: createLaneTools(options.cwd, allowedTools, options.readMemory),\n\t\tallowedTools,\n\t\tdeniedTools,\n\t\tunboundAllowPatterns,\n\t\tbeforeToolCall: async ({ toolCall, args }) => {\n\t\t\tif (!allowedToolSet.has(toolCall.name)) {\n\t\t\t\treturn { block: true, reason: `Lane tool '${toolCall.name}' is outside the materialized UAC surface.` };\n\t\t\t}\n\t\t\tconst outcome = evaluateToolGate({\n\t\t\t\ttoolName: toolCall.name,\n\t\t\t\targs,\n\t\t\t\tcwd: options.cwd,\n\t\t\t\tenvelope: WRITE_LANE_TOOL_NAME_SET.has(toolCall.name) ? writeEnvelope : readEnvelope,\n\t\t\t});\n\t\t\tif (outcome.outcome === \"allow\") return undefined;\n\t\t\treturn {\n\t\t\t\tblock: true,\n\t\t\t\treason: `Lane tool blocked (${outcome.reasonCode}): ${outcome.message ?? \"capability gate denied it\"}`,\n\t\t\t};\n\t\t},\n\t};\n}\n"]}
1
+ {"version":3,"file":"lane-tool-surface.js","sourceRoot":"","sources":["../../../src/core/autonomy/lane-tool-surface.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\nimport type { AgentLoopConfig, AgentTool } from \"@caupulican/pi-agent-core\";\nimport { type Static, Type } from \"typebox\";\nimport { CapabilityGateway, CapabilityGatewayDeniedError } from \"../orchestration/capability-gateway.ts\";\nimport type {\n\tExecutionGrant,\n\tOrchestrationExecutionPolicy,\n\tToolCapabilityManifest,\n} from \"../orchestration/contracts.ts\";\nimport type { NormalizedProfile } from \"../profile-registry.ts\";\nimport { matchesResourceProfilePattern } from \"../settings-manager.ts\";\nimport { createEditTool } from \"../tools/edit.ts\";\nimport { createFindTool } from \"../tools/find.ts\";\nimport { createGrepTool } from \"../tools/grep.ts\";\nimport { createLsTool } from \"../tools/ls.ts\";\nimport { createReadTool } from \"../tools/read.ts\";\nimport { createRunProcessTool } from \"../tools/run-process.ts\";\nimport { createWriteTool } from \"../tools/write.ts\";\nimport type { CapabilityEnvelope } from \"./contracts.ts\";\nimport { evaluateToolGate } from \"./gates.ts\";\n\nconst READ_ONLY_LANE_TOOL_NAMES = [\"read\", \"grep\", \"find\", \"ls\"] as const;\nconst MEMORY_LANE_TOOL_NAME = \"memory\" as const;\nconst WRITE_LANE_TOOL_NAMES = [\"write\", \"edit\"] as const;\nconst PROCESS_LANE_TOOL_NAME = \"run_process\" as const;\nconst laneMemorySchema = Type.Object({\n\tquery: Type.String({ description: \"What relevant standing memory or prior evidence to retrieve\" }),\n});\ntype LaneMemoryParams = Static<typeof laneMemorySchema>;\nconst WRITE_LANE_TOOL_NAME_SET = new Set<string>(WRITE_LANE_TOOL_NAMES);\n\nexport interface LaneToolSurface {\n\t/** Fresh tools owned by this lane only; no foreground tool instances or extension state leak in. */\n\ttools: AgentTool[];\n\t/** Exact names after profile globs are expanded. Safe to persist in a capability envelope. */\n\tallowedTools: string[];\n\t/** Exact safe-candidate names denied by the profile's block patterns. */\n\tdeniedTools: string[];\n\t/** Explicit grants that bind to no classified lane candidate (opaque tools stay fail-closed). */\n\tunboundAllowPatterns: string[];\n\t/** Per-call path and capability gate for the isolated child loop. */\n\tbeforeToolCall: NonNullable<AgentLoopConfig[\"beforeToolCall\"]>;\n\t/** Canonical cumulative authority/budget meter for a compiled worker grant. */\n\tgateway?: CapabilityGateway;\n}\n\nexport interface LaneToolSurfaceOptions {\n\tcwd: string;\n\tprofile?: NormalizedProfile;\n\t/** Private harness state that generic file tools must never traverse. */\n\tdeniedPaths?: readonly string[];\n\t/** Orchestrator-requested, policy-filtered read-only memory retrieval. Omitted means no memory tool. */\n\treadMemory?: (query: string) => Promise<string>;\n\t/** Research never sets this. Workers require both this flag and at least one write path. */\n\twriteEnabled?: boolean;\n\twritePaths?: readonly string[];\n\t/** Present only for process-capable owner profiles; absent means no process tool is materialized. */\n\texecutionPolicy?: OrchestrationExecutionPolicy;\n\tprocessMaxWallClockMs?: number;\n\t/** Compiled policy path. When present, it is the only authorization source for this surface. */\n\tgrant?: ExecutionGrant;\n\ttoolManifests?: readonly ToolCapabilityManifest[];\n}\n\nfunction strictLaneProfilePatterns(profile: NormalizedProfile | undefined): {\n\tallow: string[];\n\tblock: string[];\n} {\n\tif (!profile) return { allow: [], block: [] };\n\tconst filter = profile.resources.tools;\n\tconst allow = [...(filter?.allow ?? [])];\n\tconst block = [...(filter?.block ?? [])];\n\t// Strict UAC: a shipped profile is the complete authority grant. Grant-all must be explicit.\n\tif (allow.length === 0 && block.length === 0) return { allow: [], block: [\"*\"] };\n\treturn { allow, block };\n}\n\nfunction resolveWriteRoots(cwd: string, writePaths: readonly string[]): string[] {\n\treturn writePaths.map((entry) => (path.isAbsolute(entry) ? path.resolve(entry) : path.resolve(cwd, entry)));\n}\n\nfunction createLaneTools(\n\tcwd: string,\n\tnames: readonly string[],\n\treadMemory?: (query: string) => Promise<string>,\n\texecutionPolicy?: OrchestrationExecutionPolicy,\n\tprocessMaxWallClockMs = 0,\n): AgentTool[] {\n\tconst factories = new Map<string, () => AgentTool>([\n\t\t[\"read\", () => createReadTool(cwd)],\n\t\t[\"grep\", () => createGrepTool(cwd)],\n\t\t[\"find\", () => createFindTool(cwd)],\n\t\t[\"ls\", () => createLsTool(cwd)],\n\t\t[\"write\", () => createWriteTool(cwd)],\n\t\t[\"edit\", () => createEditTool(cwd)],\n\t]);\n\tif (executionPolicy) {\n\t\tfactories.set(PROCESS_LANE_TOOL_NAME, () =>\n\t\t\tcreateRunProcessTool(cwd, { policy: executionPolicy, maxWallClockMs: processMaxWallClockMs }),\n\t\t);\n\t}\n\tif (readMemory) {\n\t\tfactories.set(MEMORY_LANE_TOOL_NAME, () => ({\n\t\t\tname: MEMORY_LANE_TOOL_NAME,\n\t\t\tlabel: \"Read Memory\",\n\t\t\tdescription:\n\t\t\t\t\"Retrieve bounded, source-labeled standing memory relevant to this delegated task. Read-only: no memory writes or lifecycle actions are available.\",\n\t\t\tparameters: laneMemorySchema,\n\t\t\texecute: async (_toolCallId, params) => {\n\t\t\t\tconst { query } = params as LaneMemoryParams;\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\" as const, text: await readMemory(query) }],\n\t\t\t\t\tdetails: { readOnly: true },\n\t\t\t\t};\n\t\t\t},\n\t\t}));\n\t}\n\treturn names.flatMap((name) => {\n\t\tconst factory = factories.get(name);\n\t\treturn factory ? [factory()] : [];\n\t});\n}\n\n/**\n * Materialize a fresh, fail-closed tool surface for one isolated lane.\n *\n * Profiles select only from classified built-ins. Opaque extension tools, shell, memory, goals,\n * and `delegate` are never candidates, so a wildcard cannot manufacture unknown authority or\n * recursively spawn more workers. Write/edit additionally require the explicit worker write switch\n * and a non-empty path scope; research therefore stays read-only regardless of profile contents.\n */\nexport function createLaneToolSurface(options: LaneToolSurfaceOptions): LaneToolSurface {\n\tconst writeCapable = options.writeEnabled === true && (options.writePaths?.length ?? 0) > 0;\n\tconst candidateNames = [\n\t\t...READ_ONLY_LANE_TOOL_NAMES,\n\t\t...(options.readMemory ? [MEMORY_LANE_TOOL_NAME] : []),\n\t\t...(writeCapable ? WRITE_LANE_TOOL_NAMES : []),\n\t\t...(options.executionPolicy ? [PROCESS_LANE_TOOL_NAME] : []),\n\t];\n\tconst patterns = strictLaneProfilePatterns(options.profile);\n\tconst compiledToolNames = new Set(options.grant?.allowedTools ?? []);\n\tconst deniedTools = candidateNames.filter((name) =>\n\t\toptions.grant ? !compiledToolNames.has(name) : matchesResourceProfilePattern(name, patterns.block),\n\t);\n\tconst unboundAllowPatterns = options.grant\n\t\t? []\n\t\t: patterns.allow.filter(\n\t\t\t\t(pattern) => !candidateNames.some((name) => matchesResourceProfilePattern(name, [pattern])),\n\t\t\t);\n\tconst allowedTools = options.grant\n\t\t? candidateNames.filter((name) => compiledToolNames.has(name))\n\t\t: candidateNames.filter(\n\t\t\t\t(name) =>\n\t\t\t\t\t(patterns.allow.length === 0 || matchesResourceProfilePattern(name, patterns.allow)) &&\n\t\t\t\t\t!matchesResourceProfilePattern(name, patterns.block),\n\t\t\t);\n\tconst allowedToolSet = new Set<string>(allowedTools);\n\tconst manifestsByName = new Map(options.toolManifests?.map((manifest) => [manifest.toolName, manifest]) ?? []);\n\tif (options.grant?.allowedTools.some((name) => !manifestsByName.has(name))) {\n\t\tthrow new Error(\"Compiled lane grant references a tool without a capability manifest.\");\n\t}\n\tconst gateway = options.grant ? new CapabilityGateway({ grant: options.grant, cwd: options.cwd }) : undefined;\n\tconst deniedPaths = options.deniedPaths?.map((entry) => path.resolve(entry));\n\tconst readEnvelope: CapabilityEnvelope = {\n\t\tid: \"isolated-lane-read-tools\",\n\t\tcapabilities: [\n\t\t\t\"filesystem.read\",\n\t\t\t...(allowedToolSet.has(MEMORY_LANE_TOOL_NAME) ? ([\"memory.query\"] as const) : []),\n\t\t\t...(allowedToolSet.has(PROCESS_LANE_TOOL_NAME) ? ([\"process.exec\"] as const) : []),\n\t\t],\n\t\tallowedTools,\n\t\tdeniedTools,\n\t\tallowedPaths: [path.resolve(options.cwd)],\n\t\t...(deniedPaths && deniedPaths.length > 0 ? { deniedPaths } : {}),\n\t};\n\tconst writeEnvelope: CapabilityEnvelope = {\n\t\tid: \"isolated-lane-write-tools\",\n\t\tcapabilities: [\"filesystem.write\"],\n\t\tallowedTools,\n\t\tdeniedTools,\n\t\tallowedPaths: resolveWriteRoots(options.cwd, options.writePaths ?? []),\n\t\t...(deniedPaths && deniedPaths.length > 0 ? { deniedPaths } : {}),\n\t};\n\n\treturn {\n\t\ttools: createLaneTools(\n\t\t\toptions.cwd,\n\t\t\tallowedTools,\n\t\t\toptions.readMemory,\n\t\t\toptions.executionPolicy,\n\t\t\toptions.processMaxWallClockMs,\n\t\t),\n\t\tallowedTools,\n\t\tdeniedTools,\n\t\tunboundAllowPatterns,\n\t\tbeforeToolCall: async ({ toolCall, args }) => {\n\t\t\tif (!allowedToolSet.has(toolCall.name)) {\n\t\t\t\treturn { block: true, reason: `Lane tool '${toolCall.name}' is outside the materialized UAC surface.` };\n\t\t\t}\n\t\t\tif (gateway) {\n\t\t\t\tconst manifest = manifestsByName.get(toolCall.name);\n\t\t\t\tif (!manifest) {\n\t\t\t\t\treturn { block: true, reason: `Lane tool '${toolCall.name}' has no compiled capability manifest.` };\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tgateway.authorizeToolCall(manifest, toolCall.name, args);\n\t\t\t\t\treturn undefined;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof CapabilityGatewayDeniedError) {\n\t\t\t\t\t\treturn { block: true, reason: `Lane tool blocked (${error.reasonCode}): ${error.message}` };\n\t\t\t\t\t}\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst outcome = evaluateToolGate({\n\t\t\t\ttoolName: toolCall.name,\n\t\t\t\targs,\n\t\t\t\tcwd: options.cwd,\n\t\t\t\tenvelope: WRITE_LANE_TOOL_NAME_SET.has(toolCall.name) ? writeEnvelope : readEnvelope,\n\t\t\t});\n\t\t\tif (outcome.outcome === \"allow\") return undefined;\n\t\t\treturn {\n\t\t\t\tblock: true,\n\t\t\t\treason: `Lane tool blocked (${outcome.reasonCode}): ${outcome.message ?? \"capability gate denied it\"}`,\n\t\t\t};\n\t\t},\n\t\t...(gateway ? { gateway } : {}),\n\t};\n}\n"]}
@@ -12,6 +12,10 @@ export interface LaneRecord {
12
12
  laneId: string;
13
13
  type: LaneType;
14
14
  status: LaneStatus;
15
+ /** Bounded human-readable work label retained across session resume. */
16
+ label?: string;
17
+ /** Owner-authored profile that fixed the worker's model, thinking, tools, and budget. */
18
+ profileId?: string;
15
19
  reasonCode?: string;
16
20
  startedAt?: string;
17
21
  completedAt?: string;
@@ -44,6 +48,15 @@ export declare class LaneTracker {
44
48
  goalId?: string;
45
49
  worktreeLaneKey?: string;
46
50
  }): LaneRecord;
51
+ /** Restore an exact durable projection without minting a replacement logical id or timestamp. */
52
+ restore(record: LaneRecord): LaneRecord;
53
+ /** Start or restart a caller-named lane. The supplied id is its durable logical identity. */
54
+ startNamed(args: {
55
+ laneId: string;
56
+ type: LaneType;
57
+ goalId?: string;
58
+ worktreeLaneKey?: string;
59
+ }): LaneRecord;
47
60
  markRunning(laneId: string): LaneRecord | undefined;
48
61
  start(args: {
49
62
  type: LaneType;
@@ -59,5 +72,6 @@ export declare class LaneTracker {
59
72
  getActiveCount(type?: LaneType): number;
60
73
  getRunningCount(type?: LaneType): number;
61
74
  getRecords(): LaneRecord[];
75
+ getRecord(laneId: string): LaneRecord | undefined;
62
76
  }
63
77
  //# sourceMappingURL=lane-tracker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lane-tracker.d.ts","sourceRoot":"","sources":["../../../src/core/autonomy/lane-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,aAAa,CAAC;AAE1E,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,kBAAkB,CAAC;AAEtG,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,kBAAkB,CAAC;AAEnE,MAAM,WAAW,UAAU;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAMD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,kBAAkB,CAEhF;AAMD,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAgBhE;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAExE;AAKD,qBAAa,WAAW;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IACxD,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAe;IAEpC,YAAY,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;KAAE,EAE3C;IAED,kGAAkG;IAClG,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAIvC;IAED,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU,CAWvF;IAED,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAMlD;IAED,KAAK,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU,CAGrF;IAED,QAAQ,CACP,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;QAAE,MAAM,EAAE,kBAAkB,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GACnG,UAAU,GAAG,SAAS,CAcxB;IAED,cAAc,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,CAQtC;IAED,eAAe,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,CAQvC;IAED,UAAU,IAAI,UAAU,EAAE,CAEzB;CACD","sourcesContent":["/**\n * Live lane registry for autonomous background work (research/worker/learning lanes).\n *\n * This is the first real concurrency tracker behind `AutonomyStatusSnapshot.activeLaneCount`:\n * counts reflect lanes actually running in THIS process, never inferred/faked from historical\n * snapshots. Terminal lane records are persisted separately via `session-lane-record.ts`.\n */\n\nexport type LaneType = \"research\" | \"worker\" | \"learning\" | \"tmux-worker\";\n\nexport type LaneTerminalStatus = \"succeeded\" | \"failed\" | \"canceled\" | \"timeout\" | \"budget_exhausted\";\n\nexport type LaneStatus = \"queued\" | \"running\" | LaneTerminalStatus;\n\nexport interface LaneRecord {\n\tlaneId: string;\n\ttype: LaneType;\n\tstatus: LaneStatus;\n\treasonCode?: string;\n\tstartedAt?: string;\n\tcompletedAt?: string;\n\tcostUsd?: number;\n\tgoalId?: string;\n\tevidenceEntryId?: string;\n\t/**\n\t * Worktree-sync lane key this lane record was correlated to at dispatch (set only for a\n\t * tmux-worker lane whose fire_task carried a `worktreeLane` -- see `tmux-dispatch.ts`'s\n\t * `createLaneWorktree`). Optional so every pre-existing record/caller keeps compiling and\n\t * behaving unchanged; `undefined` for a lane never bound to a worktree-sync lane.\n\t */\n\tworktreeLaneKey?: string;\n}\n\nconst LANE_TYPES: readonly string[] = [\"research\", \"worker\", \"learning\", \"tmux-worker\"];\nconst TERMINAL_STATUSES: readonly string[] = [\"succeeded\", \"failed\", \"canceled\", \"timeout\", \"budget_exhausted\"];\nconst LANE_STATUSES: readonly string[] = [\"queued\", \"running\", ...TERMINAL_STATUSES];\n\nexport function isLaneTerminalStatus(value: unknown): value is LaneTerminalStatus {\n\treturn typeof value === \"string\" && TERMINAL_STATUSES.includes(value);\n}\n\nfunction isOptionalString(value: unknown): boolean {\n\treturn value === undefined || typeof value === \"string\";\n}\n\nexport function isLaneRecord(value: unknown): value is LaneRecord {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst record = value as Record<string, unknown>;\n\tif (typeof record.laneId !== \"string\" || record.laneId.length === 0) return false;\n\tif (typeof record.type !== \"string\" || !LANE_TYPES.includes(record.type)) return false;\n\tif (typeof record.status !== \"string\" || !LANE_STATUSES.includes(record.status)) return false;\n\tif (!isOptionalString(record.reasonCode)) return false;\n\tif (!isOptionalString(record.startedAt)) return false;\n\tif (!isOptionalString(record.completedAt)) return false;\n\tif (record.costUsd !== undefined && (typeof record.costUsd !== \"number\" || !Number.isFinite(record.costUsd))) {\n\t\treturn false;\n\t}\n\tif (!isOptionalString(record.goalId)) return false;\n\tif (!isOptionalString(record.evidenceEntryId)) return false;\n\tif (!isOptionalString(record.worktreeLaneKey)) return false;\n\treturn true;\n}\n\nexport function cloneLaneRecordForStorage(record: LaneRecord): LaneRecord {\n\treturn { ...record };\n}\n\n/** Terminal records kept in memory for diagnostics; older ones are evicted (the session log holds history). */\nconst MAX_TERMINAL_LANES_IN_MEMORY = 100;\n\nexport class LaneTracker {\n\tprivate readonly _lanes = new Map<string, LaneRecord>();\n\tprivate _nextLaneNumber = 1;\n\tprivate readonly _now: () => string;\n\n\tconstructor(options?: { now?: () => string }) {\n\t\tthis._now = options?.now ?? (() => new Date().toISOString());\n\t}\n\n\t/** Seed the id counter (e.g. from persisted lane records) so resumed sessions don't reuse ids. */\n\tensureCounterAtLeast(next: number): void {\n\t\tif (Number.isFinite(next) && next > this._nextLaneNumber) {\n\t\t\tthis._nextLaneNumber = Math.floor(next);\n\t\t}\n\t}\n\n\tprivate _evictOldTerminal(): void {\n\t\tlet terminal = 0;\n\t\tfor (const record of this._lanes.values()) {\n\t\t\tif (isLaneTerminalStatus(record.status)) terminal++;\n\t\t}\n\t\tif (terminal <= MAX_TERMINAL_LANES_IN_MEMORY) return;\n\t\t// Map iteration is insertion-ordered: drop oldest terminal records first.\n\t\tfor (const [laneId, record] of this._lanes) {\n\t\t\tif (terminal <= MAX_TERMINAL_LANES_IN_MEMORY) break;\n\t\t\tif (isLaneTerminalStatus(record.status)) {\n\t\t\t\tthis._lanes.delete(laneId);\n\t\t\t\tterminal--;\n\t\t\t}\n\t\t}\n\t}\n\n\tenqueue(args: { type: LaneType; goalId?: string; worktreeLaneKey?: string }): LaneRecord {\n\t\tconst laneId = `${args.type}-${this._nextLaneNumber++}`;\n\t\tconst record: LaneRecord = {\n\t\t\tlaneId,\n\t\t\ttype: args.type,\n\t\t\tstatus: \"queued\",\n\t\t};\n\t\tif (args.goalId !== undefined) record.goalId = args.goalId;\n\t\tif (args.worktreeLaneKey !== undefined) record.worktreeLaneKey = args.worktreeLaneKey;\n\t\tthis._lanes.set(laneId, record);\n\t\treturn { ...record };\n\t}\n\n\tmarkRunning(laneId: string): LaneRecord | undefined {\n\t\tconst record = this._lanes.get(laneId);\n\t\tif (!record || record.status !== \"queued\") return undefined;\n\t\tconst next = { ...record, status: \"running\" as const, startedAt: this._now() };\n\t\tthis._lanes.set(laneId, next);\n\t\treturn { ...next };\n\t}\n\n\tstart(args: { type: LaneType; goalId?: string; worktreeLaneKey?: string }): LaneRecord {\n\t\tconst record = this.enqueue(args);\n\t\treturn this.markRunning(record.laneId) as LaneRecord;\n\t}\n\n\tcomplete(\n\t\tlaneId: string,\n\t\targs: { status: LaneTerminalStatus; reasonCode?: string; costUsd?: number; evidenceEntryId?: string },\n\t): LaneRecord | undefined {\n\t\tconst record = this._lanes.get(laneId);\n\t\tif (!record || isLaneTerminalStatus(record.status)) return undefined;\n\t\tconst next: LaneRecord = {\n\t\t\t...record,\n\t\t\tstatus: args.status,\n\t\t\tcompletedAt: this._now(),\n\t\t};\n\t\tif (args.reasonCode !== undefined) next.reasonCode = args.reasonCode;\n\t\tif (args.costUsd !== undefined) next.costUsd = args.costUsd;\n\t\tif (args.evidenceEntryId !== undefined) next.evidenceEntryId = args.evidenceEntryId;\n\t\tthis._lanes.set(laneId, next);\n\t\tthis._evictOldTerminal();\n\t\treturn { ...next };\n\t}\n\n\tgetActiveCount(type?: LaneType): number {\n\t\tlet count = 0;\n\t\tfor (const record of this._lanes.values()) {\n\t\t\tif (isLaneTerminalStatus(record.status)) continue;\n\t\t\tif (type !== undefined && record.type !== type) continue;\n\t\t\tcount++;\n\t\t}\n\t\treturn count;\n\t}\n\n\tgetRunningCount(type?: LaneType): number {\n\t\tlet count = 0;\n\t\tfor (const record of this._lanes.values()) {\n\t\t\tif (record.status !== \"running\") continue;\n\t\t\tif (type !== undefined && record.type !== type) continue;\n\t\t\tcount++;\n\t\t}\n\t\treturn count;\n\t}\n\n\tgetRecords(): LaneRecord[] {\n\t\treturn [...this._lanes.values()].map((record) => ({ ...record }));\n\t}\n}\n"]}
1
+ {"version":3,"file":"lane-tracker.d.ts","sourceRoot":"","sources":["../../../src/core/autonomy/lane-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,aAAa,CAAC;AAE1E,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,kBAAkB,CAAC;AAEtG,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,kBAAkB,CAAC;AAEnE,MAAM,WAAW,UAAU;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,UAAU,CAAC;IACnB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yFAAyF;IACzF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAMD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,kBAAkB,CAEhF;AAMD,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAkBhE;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAExE;AAKD,qBAAa,WAAW;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IACxD,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAe;IAEpC,YAAY,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;KAAE,EAE3C;IAED,kGAAkG;IAClG,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAIvC;IAED,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU,CAWvF;IAED,iGAAiG;IACjG,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAOtC;IAED,6FAA6F;IAC7F,UAAU,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU,CAc1G;IAED,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAMlD;IAED,KAAK,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU,CAGrF;IAED,QAAQ,CACP,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;QAAE,MAAM,EAAE,kBAAkB,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GACnG,UAAU,GAAG,SAAS,CAcxB;IAED,cAAc,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,CAQtC;IAED,eAAe,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,CAQvC;IAED,UAAU,IAAI,UAAU,EAAE,CAEzB;IAED,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAGhD;CACD","sourcesContent":["/**\n * Live lane registry for autonomous background work (research/worker/learning lanes).\n *\n * This is the first real concurrency tracker behind `AutonomyStatusSnapshot.activeLaneCount`:\n * counts reflect lanes actually running in THIS process, never inferred/faked from historical\n * snapshots. Terminal lane records are persisted separately via `session-lane-record.ts`.\n */\n\nexport type LaneType = \"research\" | \"worker\" | \"learning\" | \"tmux-worker\";\n\nexport type LaneTerminalStatus = \"succeeded\" | \"failed\" | \"canceled\" | \"timeout\" | \"budget_exhausted\";\n\nexport type LaneStatus = \"queued\" | \"running\" | LaneTerminalStatus;\n\nexport interface LaneRecord {\n\tlaneId: string;\n\ttype: LaneType;\n\tstatus: LaneStatus;\n\t/** Bounded human-readable work label retained across session resume. */\n\tlabel?: string;\n\t/** Owner-authored profile that fixed the worker's model, thinking, tools, and budget. */\n\tprofileId?: string;\n\treasonCode?: string;\n\tstartedAt?: string;\n\tcompletedAt?: string;\n\tcostUsd?: number;\n\tgoalId?: string;\n\tevidenceEntryId?: string;\n\t/**\n\t * Worktree-sync lane key this lane record was correlated to at dispatch (set only for a\n\t * tmux-worker lane whose fire_task carried a `worktreeLane` -- see `tmux-dispatch.ts`'s\n\t * `createLaneWorktree`). Optional so every pre-existing record/caller keeps compiling and\n\t * behaving unchanged; `undefined` for a lane never bound to a worktree-sync lane.\n\t */\n\tworktreeLaneKey?: string;\n}\n\nconst LANE_TYPES: readonly string[] = [\"research\", \"worker\", \"learning\", \"tmux-worker\"];\nconst TERMINAL_STATUSES: readonly string[] = [\"succeeded\", \"failed\", \"canceled\", \"timeout\", \"budget_exhausted\"];\nconst LANE_STATUSES: readonly string[] = [\"queued\", \"running\", ...TERMINAL_STATUSES];\n\nexport function isLaneTerminalStatus(value: unknown): value is LaneTerminalStatus {\n\treturn typeof value === \"string\" && TERMINAL_STATUSES.includes(value);\n}\n\nfunction isOptionalString(value: unknown): boolean {\n\treturn value === undefined || typeof value === \"string\";\n}\n\nexport function isLaneRecord(value: unknown): value is LaneRecord {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst record = value as Record<string, unknown>;\n\tif (typeof record.laneId !== \"string\" || record.laneId.length === 0) return false;\n\tif (typeof record.type !== \"string\" || !LANE_TYPES.includes(record.type)) return false;\n\tif (typeof record.status !== \"string\" || !LANE_STATUSES.includes(record.status)) return false;\n\tif (!isOptionalString(record.label)) return false;\n\tif (!isOptionalString(record.profileId)) return false;\n\tif (!isOptionalString(record.reasonCode)) return false;\n\tif (!isOptionalString(record.startedAt)) return false;\n\tif (!isOptionalString(record.completedAt)) return false;\n\tif (record.costUsd !== undefined && (typeof record.costUsd !== \"number\" || !Number.isFinite(record.costUsd))) {\n\t\treturn false;\n\t}\n\tif (!isOptionalString(record.goalId)) return false;\n\tif (!isOptionalString(record.evidenceEntryId)) return false;\n\tif (!isOptionalString(record.worktreeLaneKey)) return false;\n\treturn true;\n}\n\nexport function cloneLaneRecordForStorage(record: LaneRecord): LaneRecord {\n\treturn { ...record };\n}\n\n/** Terminal records kept in memory for diagnostics; older ones are evicted (the session log holds history). */\nconst MAX_TERMINAL_LANES_IN_MEMORY = 100;\n\nexport class LaneTracker {\n\tprivate readonly _lanes = new Map<string, LaneRecord>();\n\tprivate _nextLaneNumber = 1;\n\tprivate readonly _now: () => string;\n\n\tconstructor(options?: { now?: () => string }) {\n\t\tthis._now = options?.now ?? (() => new Date().toISOString());\n\t}\n\n\t/** Seed the id counter (e.g. from persisted lane records) so resumed sessions don't reuse ids. */\n\tensureCounterAtLeast(next: number): void {\n\t\tif (Number.isFinite(next) && next > this._nextLaneNumber) {\n\t\t\tthis._nextLaneNumber = Math.floor(next);\n\t\t}\n\t}\n\n\tprivate _evictOldTerminal(): void {\n\t\tlet terminal = 0;\n\t\tfor (const record of this._lanes.values()) {\n\t\t\tif (isLaneTerminalStatus(record.status)) terminal++;\n\t\t}\n\t\tif (terminal <= MAX_TERMINAL_LANES_IN_MEMORY) return;\n\t\t// Map iteration is insertion-ordered: drop oldest terminal records first.\n\t\tfor (const [laneId, record] of this._lanes) {\n\t\t\tif (terminal <= MAX_TERMINAL_LANES_IN_MEMORY) break;\n\t\t\tif (isLaneTerminalStatus(record.status)) {\n\t\t\t\tthis._lanes.delete(laneId);\n\t\t\t\tterminal--;\n\t\t\t}\n\t\t}\n\t}\n\n\tenqueue(args: { type: LaneType; goalId?: string; worktreeLaneKey?: string }): LaneRecord {\n\t\tconst laneId = `${args.type}-${this._nextLaneNumber++}`;\n\t\tconst record: LaneRecord = {\n\t\t\tlaneId,\n\t\t\ttype: args.type,\n\t\t\tstatus: \"queued\",\n\t\t};\n\t\tif (args.goalId !== undefined) record.goalId = args.goalId;\n\t\tif (args.worktreeLaneKey !== undefined) record.worktreeLaneKey = args.worktreeLaneKey;\n\t\tthis._lanes.set(laneId, record);\n\t\treturn { ...record };\n\t}\n\n\t/** Restore an exact durable projection without minting a replacement logical id or timestamp. */\n\trestore(record: LaneRecord): LaneRecord {\n\t\tconst restored = { ...record };\n\t\tthis._lanes.set(restored.laneId, restored);\n\t\tconst suffix = /-(\\d+)$/.exec(restored.laneId)?.[1];\n\t\tif (suffix) this.ensureCounterAtLeast(Number(suffix) + 1);\n\t\tthis._evictOldTerminal();\n\t\treturn { ...restored };\n\t}\n\n\t/** Start or restart a caller-named lane. The supplied id is its durable logical identity. */\n\tstartNamed(args: { laneId: string; type: LaneType; goalId?: string; worktreeLaneKey?: string }): LaneRecord {\n\t\tif (!args.laneId) throw new TypeError(\"A named lane requires a non-empty laneId.\");\n\t\tconst record: LaneRecord = {\n\t\t\tlaneId: args.laneId,\n\t\t\ttype: args.type,\n\t\t\tstatus: \"running\",\n\t\t\tstartedAt: this._now(),\n\t\t};\n\t\tif (args.goalId !== undefined) record.goalId = args.goalId;\n\t\tif (args.worktreeLaneKey !== undefined) record.worktreeLaneKey = args.worktreeLaneKey;\n\t\tthis._lanes.set(record.laneId, record);\n\t\tconst suffix = /-(\\d+)$/.exec(record.laneId)?.[1];\n\t\tif (suffix) this.ensureCounterAtLeast(Number(suffix) + 1);\n\t\treturn { ...record };\n\t}\n\n\tmarkRunning(laneId: string): LaneRecord | undefined {\n\t\tconst record = this._lanes.get(laneId);\n\t\tif (!record || record.status !== \"queued\") return undefined;\n\t\tconst next = { ...record, status: \"running\" as const, startedAt: this._now() };\n\t\tthis._lanes.set(laneId, next);\n\t\treturn { ...next };\n\t}\n\n\tstart(args: { type: LaneType; goalId?: string; worktreeLaneKey?: string }): LaneRecord {\n\t\tconst record = this.enqueue(args);\n\t\treturn this.markRunning(record.laneId) as LaneRecord;\n\t}\n\n\tcomplete(\n\t\tlaneId: string,\n\t\targs: { status: LaneTerminalStatus; reasonCode?: string; costUsd?: number; evidenceEntryId?: string },\n\t): LaneRecord | undefined {\n\t\tconst record = this._lanes.get(laneId);\n\t\tif (!record || isLaneTerminalStatus(record.status)) return undefined;\n\t\tconst next: LaneRecord = {\n\t\t\t...record,\n\t\t\tstatus: args.status,\n\t\t\tcompletedAt: this._now(),\n\t\t};\n\t\tif (args.reasonCode !== undefined) next.reasonCode = args.reasonCode;\n\t\tif (args.costUsd !== undefined) next.costUsd = args.costUsd;\n\t\tif (args.evidenceEntryId !== undefined) next.evidenceEntryId = args.evidenceEntryId;\n\t\tthis._lanes.set(laneId, next);\n\t\tthis._evictOldTerminal();\n\t\treturn { ...next };\n\t}\n\n\tgetActiveCount(type?: LaneType): number {\n\t\tlet count = 0;\n\t\tfor (const record of this._lanes.values()) {\n\t\t\tif (isLaneTerminalStatus(record.status)) continue;\n\t\t\tif (type !== undefined && record.type !== type) continue;\n\t\t\tcount++;\n\t\t}\n\t\treturn count;\n\t}\n\n\tgetRunningCount(type?: LaneType): number {\n\t\tlet count = 0;\n\t\tfor (const record of this._lanes.values()) {\n\t\t\tif (record.status !== \"running\") continue;\n\t\t\tif (type !== undefined && record.type !== type) continue;\n\t\t\tcount++;\n\t\t}\n\t\treturn count;\n\t}\n\n\tgetRecords(): LaneRecord[] {\n\t\treturn [...this._lanes.values()].map((record) => ({ ...record }));\n\t}\n\n\tgetRecord(laneId: string): LaneRecord | undefined {\n\t\tconst record = this._lanes.get(laneId);\n\t\treturn record ? { ...record } : undefined;\n\t}\n}\n"]}
@@ -24,6 +24,10 @@ export function isLaneRecord(value) {
24
24
  return false;
25
25
  if (typeof record.status !== "string" || !LANE_STATUSES.includes(record.status))
26
26
  return false;
27
+ if (!isOptionalString(record.label))
28
+ return false;
29
+ if (!isOptionalString(record.profileId))
30
+ return false;
27
31
  if (!isOptionalString(record.reasonCode))
28
32
  return false;
29
33
  if (!isOptionalString(record.startedAt))
@@ -91,6 +95,36 @@ export class LaneTracker {
91
95
  this._lanes.set(laneId, record);
92
96
  return { ...record };
93
97
  }
98
+ /** Restore an exact durable projection without minting a replacement logical id or timestamp. */
99
+ restore(record) {
100
+ const restored = { ...record };
101
+ this._lanes.set(restored.laneId, restored);
102
+ const suffix = /-(\d+)$/.exec(restored.laneId)?.[1];
103
+ if (suffix)
104
+ this.ensureCounterAtLeast(Number(suffix) + 1);
105
+ this._evictOldTerminal();
106
+ return { ...restored };
107
+ }
108
+ /** Start or restart a caller-named lane. The supplied id is its durable logical identity. */
109
+ startNamed(args) {
110
+ if (!args.laneId)
111
+ throw new TypeError("A named lane requires a non-empty laneId.");
112
+ const record = {
113
+ laneId: args.laneId,
114
+ type: args.type,
115
+ status: "running",
116
+ startedAt: this._now(),
117
+ };
118
+ if (args.goalId !== undefined)
119
+ record.goalId = args.goalId;
120
+ if (args.worktreeLaneKey !== undefined)
121
+ record.worktreeLaneKey = args.worktreeLaneKey;
122
+ this._lanes.set(record.laneId, record);
123
+ const suffix = /-(\d+)$/.exec(record.laneId)?.[1];
124
+ if (suffix)
125
+ this.ensureCounterAtLeast(Number(suffix) + 1);
126
+ return { ...record };
127
+ }
94
128
  markRunning(laneId) {
95
129
  const record = this._lanes.get(laneId);
96
130
  if (!record || record.status !== "queued")
@@ -147,5 +181,9 @@ export class LaneTracker {
147
181
  getRecords() {
148
182
  return [...this._lanes.values()].map((record) => ({ ...record }));
149
183
  }
184
+ getRecord(laneId) {
185
+ const record = this._lanes.get(laneId);
186
+ return record ? { ...record } : undefined;
187
+ }
150
188
  }
151
189
  //# sourceMappingURL=lane-tracker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lane-tracker.js","sourceRoot":"","sources":["../../../src/core/autonomy/lane-tracker.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Live lane registry for autonomous background work (research/worker/learning lanes).\n *\n * This is the first real concurrency tracker behind `AutonomyStatusSnapshot.activeLaneCount`:\n * counts reflect lanes actually running in THIS process, never inferred/faked from historical\n * snapshots. Terminal lane records are persisted separately via `session-lane-record.ts`.\n */\n\nexport type LaneType = \"research\" | \"worker\" | \"learning\" | \"tmux-worker\";\n\nexport type LaneTerminalStatus = \"succeeded\" | \"failed\" | \"canceled\" | \"timeout\" | \"budget_exhausted\";\n\nexport type LaneStatus = \"queued\" | \"running\" | LaneTerminalStatus;\n\nexport interface LaneRecord {\n\tlaneId: string;\n\ttype: LaneType;\n\tstatus: LaneStatus;\n\treasonCode?: string;\n\tstartedAt?: string;\n\tcompletedAt?: string;\n\tcostUsd?: number;\n\tgoalId?: string;\n\tevidenceEntryId?: string;\n\t/**\n\t * Worktree-sync lane key this lane record was correlated to at dispatch (set only for a\n\t * tmux-worker lane whose fire_task carried a `worktreeLane` -- see `tmux-dispatch.ts`'s\n\t * `createLaneWorktree`). Optional so every pre-existing record/caller keeps compiling and\n\t * behaving unchanged; `undefined` for a lane never bound to a worktree-sync lane.\n\t */\n\tworktreeLaneKey?: string;\n}\n\nconst LANE_TYPES: readonly string[] = [\"research\", \"worker\", \"learning\", \"tmux-worker\"];\nconst TERMINAL_STATUSES: readonly string[] = [\"succeeded\", \"failed\", \"canceled\", \"timeout\", \"budget_exhausted\"];\nconst LANE_STATUSES: readonly string[] = [\"queued\", \"running\", ...TERMINAL_STATUSES];\n\nexport function isLaneTerminalStatus(value: unknown): value is LaneTerminalStatus {\n\treturn typeof value === \"string\" && TERMINAL_STATUSES.includes(value);\n}\n\nfunction isOptionalString(value: unknown): boolean {\n\treturn value === undefined || typeof value === \"string\";\n}\n\nexport function isLaneRecord(value: unknown): value is LaneRecord {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst record = value as Record<string, unknown>;\n\tif (typeof record.laneId !== \"string\" || record.laneId.length === 0) return false;\n\tif (typeof record.type !== \"string\" || !LANE_TYPES.includes(record.type)) return false;\n\tif (typeof record.status !== \"string\" || !LANE_STATUSES.includes(record.status)) return false;\n\tif (!isOptionalString(record.reasonCode)) return false;\n\tif (!isOptionalString(record.startedAt)) return false;\n\tif (!isOptionalString(record.completedAt)) return false;\n\tif (record.costUsd !== undefined && (typeof record.costUsd !== \"number\" || !Number.isFinite(record.costUsd))) {\n\t\treturn false;\n\t}\n\tif (!isOptionalString(record.goalId)) return false;\n\tif (!isOptionalString(record.evidenceEntryId)) return false;\n\tif (!isOptionalString(record.worktreeLaneKey)) return false;\n\treturn true;\n}\n\nexport function cloneLaneRecordForStorage(record: LaneRecord): LaneRecord {\n\treturn { ...record };\n}\n\n/** Terminal records kept in memory for diagnostics; older ones are evicted (the session log holds history). */\nconst MAX_TERMINAL_LANES_IN_MEMORY = 100;\n\nexport class LaneTracker {\n\tprivate readonly _lanes = new Map<string, LaneRecord>();\n\tprivate _nextLaneNumber = 1;\n\tprivate readonly _now: () => string;\n\n\tconstructor(options?: { now?: () => string }) {\n\t\tthis._now = options?.now ?? (() => new Date().toISOString());\n\t}\n\n\t/** Seed the id counter (e.g. from persisted lane records) so resumed sessions don't reuse ids. */\n\tensureCounterAtLeast(next: number): void {\n\t\tif (Number.isFinite(next) && next > this._nextLaneNumber) {\n\t\t\tthis._nextLaneNumber = Math.floor(next);\n\t\t}\n\t}\n\n\tprivate _evictOldTerminal(): void {\n\t\tlet terminal = 0;\n\t\tfor (const record of this._lanes.values()) {\n\t\t\tif (isLaneTerminalStatus(record.status)) terminal++;\n\t\t}\n\t\tif (terminal <= MAX_TERMINAL_LANES_IN_MEMORY) return;\n\t\t// Map iteration is insertion-ordered: drop oldest terminal records first.\n\t\tfor (const [laneId, record] of this._lanes) {\n\t\t\tif (terminal <= MAX_TERMINAL_LANES_IN_MEMORY) break;\n\t\t\tif (isLaneTerminalStatus(record.status)) {\n\t\t\t\tthis._lanes.delete(laneId);\n\t\t\t\tterminal--;\n\t\t\t}\n\t\t}\n\t}\n\n\tenqueue(args: { type: LaneType; goalId?: string; worktreeLaneKey?: string }): LaneRecord {\n\t\tconst laneId = `${args.type}-${this._nextLaneNumber++}`;\n\t\tconst record: LaneRecord = {\n\t\t\tlaneId,\n\t\t\ttype: args.type,\n\t\t\tstatus: \"queued\",\n\t\t};\n\t\tif (args.goalId !== undefined) record.goalId = args.goalId;\n\t\tif (args.worktreeLaneKey !== undefined) record.worktreeLaneKey = args.worktreeLaneKey;\n\t\tthis._lanes.set(laneId, record);\n\t\treturn { ...record };\n\t}\n\n\tmarkRunning(laneId: string): LaneRecord | undefined {\n\t\tconst record = this._lanes.get(laneId);\n\t\tif (!record || record.status !== \"queued\") return undefined;\n\t\tconst next = { ...record, status: \"running\" as const, startedAt: this._now() };\n\t\tthis._lanes.set(laneId, next);\n\t\treturn { ...next };\n\t}\n\n\tstart(args: { type: LaneType; goalId?: string; worktreeLaneKey?: string }): LaneRecord {\n\t\tconst record = this.enqueue(args);\n\t\treturn this.markRunning(record.laneId) as LaneRecord;\n\t}\n\n\tcomplete(\n\t\tlaneId: string,\n\t\targs: { status: LaneTerminalStatus; reasonCode?: string; costUsd?: number; evidenceEntryId?: string },\n\t): LaneRecord | undefined {\n\t\tconst record = this._lanes.get(laneId);\n\t\tif (!record || isLaneTerminalStatus(record.status)) return undefined;\n\t\tconst next: LaneRecord = {\n\t\t\t...record,\n\t\t\tstatus: args.status,\n\t\t\tcompletedAt: this._now(),\n\t\t};\n\t\tif (args.reasonCode !== undefined) next.reasonCode = args.reasonCode;\n\t\tif (args.costUsd !== undefined) next.costUsd = args.costUsd;\n\t\tif (args.evidenceEntryId !== undefined) next.evidenceEntryId = args.evidenceEntryId;\n\t\tthis._lanes.set(laneId, next);\n\t\tthis._evictOldTerminal();\n\t\treturn { ...next };\n\t}\n\n\tgetActiveCount(type?: LaneType): number {\n\t\tlet count = 0;\n\t\tfor (const record of this._lanes.values()) {\n\t\t\tif (isLaneTerminalStatus(record.status)) continue;\n\t\t\tif (type !== undefined && record.type !== type) continue;\n\t\t\tcount++;\n\t\t}\n\t\treturn count;\n\t}\n\n\tgetRunningCount(type?: LaneType): number {\n\t\tlet count = 0;\n\t\tfor (const record of this._lanes.values()) {\n\t\t\tif (record.status !== \"running\") continue;\n\t\t\tif (type !== undefined && record.type !== type) continue;\n\t\t\tcount++;\n\t\t}\n\t\treturn count;\n\t}\n\n\tgetRecords(): LaneRecord[] {\n\t\treturn [...this._lanes.values()].map((record) => ({ ...record }));\n\t}\n}\n"]}
1
+ {"version":3,"file":"lane-tracker.js","sourceRoot":"","sources":["../../../src/core/autonomy/lane-tracker.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Live lane registry for autonomous background work (research/worker/learning lanes).\n *\n * This is the first real concurrency tracker behind `AutonomyStatusSnapshot.activeLaneCount`:\n * counts reflect lanes actually running in THIS process, never inferred/faked from historical\n * snapshots. Terminal lane records are persisted separately via `session-lane-record.ts`.\n */\n\nexport type LaneType = \"research\" | \"worker\" | \"learning\" | \"tmux-worker\";\n\nexport type LaneTerminalStatus = \"succeeded\" | \"failed\" | \"canceled\" | \"timeout\" | \"budget_exhausted\";\n\nexport type LaneStatus = \"queued\" | \"running\" | LaneTerminalStatus;\n\nexport interface LaneRecord {\n\tlaneId: string;\n\ttype: LaneType;\n\tstatus: LaneStatus;\n\t/** Bounded human-readable work label retained across session resume. */\n\tlabel?: string;\n\t/** Owner-authored profile that fixed the worker's model, thinking, tools, and budget. */\n\tprofileId?: string;\n\treasonCode?: string;\n\tstartedAt?: string;\n\tcompletedAt?: string;\n\tcostUsd?: number;\n\tgoalId?: string;\n\tevidenceEntryId?: string;\n\t/**\n\t * Worktree-sync lane key this lane record was correlated to at dispatch (set only for a\n\t * tmux-worker lane whose fire_task carried a `worktreeLane` -- see `tmux-dispatch.ts`'s\n\t * `createLaneWorktree`). Optional so every pre-existing record/caller keeps compiling and\n\t * behaving unchanged; `undefined` for a lane never bound to a worktree-sync lane.\n\t */\n\tworktreeLaneKey?: string;\n}\n\nconst LANE_TYPES: readonly string[] = [\"research\", \"worker\", \"learning\", \"tmux-worker\"];\nconst TERMINAL_STATUSES: readonly string[] = [\"succeeded\", \"failed\", \"canceled\", \"timeout\", \"budget_exhausted\"];\nconst LANE_STATUSES: readonly string[] = [\"queued\", \"running\", ...TERMINAL_STATUSES];\n\nexport function isLaneTerminalStatus(value: unknown): value is LaneTerminalStatus {\n\treturn typeof value === \"string\" && TERMINAL_STATUSES.includes(value);\n}\n\nfunction isOptionalString(value: unknown): boolean {\n\treturn value === undefined || typeof value === \"string\";\n}\n\nexport function isLaneRecord(value: unknown): value is LaneRecord {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst record = value as Record<string, unknown>;\n\tif (typeof record.laneId !== \"string\" || record.laneId.length === 0) return false;\n\tif (typeof record.type !== \"string\" || !LANE_TYPES.includes(record.type)) return false;\n\tif (typeof record.status !== \"string\" || !LANE_STATUSES.includes(record.status)) return false;\n\tif (!isOptionalString(record.label)) return false;\n\tif (!isOptionalString(record.profileId)) return false;\n\tif (!isOptionalString(record.reasonCode)) return false;\n\tif (!isOptionalString(record.startedAt)) return false;\n\tif (!isOptionalString(record.completedAt)) return false;\n\tif (record.costUsd !== undefined && (typeof record.costUsd !== \"number\" || !Number.isFinite(record.costUsd))) {\n\t\treturn false;\n\t}\n\tif (!isOptionalString(record.goalId)) return false;\n\tif (!isOptionalString(record.evidenceEntryId)) return false;\n\tif (!isOptionalString(record.worktreeLaneKey)) return false;\n\treturn true;\n}\n\nexport function cloneLaneRecordForStorage(record: LaneRecord): LaneRecord {\n\treturn { ...record };\n}\n\n/** Terminal records kept in memory for diagnostics; older ones are evicted (the session log holds history). */\nconst MAX_TERMINAL_LANES_IN_MEMORY = 100;\n\nexport class LaneTracker {\n\tprivate readonly _lanes = new Map<string, LaneRecord>();\n\tprivate _nextLaneNumber = 1;\n\tprivate readonly _now: () => string;\n\n\tconstructor(options?: { now?: () => string }) {\n\t\tthis._now = options?.now ?? (() => new Date().toISOString());\n\t}\n\n\t/** Seed the id counter (e.g. from persisted lane records) so resumed sessions don't reuse ids. */\n\tensureCounterAtLeast(next: number): void {\n\t\tif (Number.isFinite(next) && next > this._nextLaneNumber) {\n\t\t\tthis._nextLaneNumber = Math.floor(next);\n\t\t}\n\t}\n\n\tprivate _evictOldTerminal(): void {\n\t\tlet terminal = 0;\n\t\tfor (const record of this._lanes.values()) {\n\t\t\tif (isLaneTerminalStatus(record.status)) terminal++;\n\t\t}\n\t\tif (terminal <= MAX_TERMINAL_LANES_IN_MEMORY) return;\n\t\t// Map iteration is insertion-ordered: drop oldest terminal records first.\n\t\tfor (const [laneId, record] of this._lanes) {\n\t\t\tif (terminal <= MAX_TERMINAL_LANES_IN_MEMORY) break;\n\t\t\tif (isLaneTerminalStatus(record.status)) {\n\t\t\t\tthis._lanes.delete(laneId);\n\t\t\t\tterminal--;\n\t\t\t}\n\t\t}\n\t}\n\n\tenqueue(args: { type: LaneType; goalId?: string; worktreeLaneKey?: string }): LaneRecord {\n\t\tconst laneId = `${args.type}-${this._nextLaneNumber++}`;\n\t\tconst record: LaneRecord = {\n\t\t\tlaneId,\n\t\t\ttype: args.type,\n\t\t\tstatus: \"queued\",\n\t\t};\n\t\tif (args.goalId !== undefined) record.goalId = args.goalId;\n\t\tif (args.worktreeLaneKey !== undefined) record.worktreeLaneKey = args.worktreeLaneKey;\n\t\tthis._lanes.set(laneId, record);\n\t\treturn { ...record };\n\t}\n\n\t/** Restore an exact durable projection without minting a replacement logical id or timestamp. */\n\trestore(record: LaneRecord): LaneRecord {\n\t\tconst restored = { ...record };\n\t\tthis._lanes.set(restored.laneId, restored);\n\t\tconst suffix = /-(\\d+)$/.exec(restored.laneId)?.[1];\n\t\tif (suffix) this.ensureCounterAtLeast(Number(suffix) + 1);\n\t\tthis._evictOldTerminal();\n\t\treturn { ...restored };\n\t}\n\n\t/** Start or restart a caller-named lane. The supplied id is its durable logical identity. */\n\tstartNamed(args: { laneId: string; type: LaneType; goalId?: string; worktreeLaneKey?: string }): LaneRecord {\n\t\tif (!args.laneId) throw new TypeError(\"A named lane requires a non-empty laneId.\");\n\t\tconst record: LaneRecord = {\n\t\t\tlaneId: args.laneId,\n\t\t\ttype: args.type,\n\t\t\tstatus: \"running\",\n\t\t\tstartedAt: this._now(),\n\t\t};\n\t\tif (args.goalId !== undefined) record.goalId = args.goalId;\n\t\tif (args.worktreeLaneKey !== undefined) record.worktreeLaneKey = args.worktreeLaneKey;\n\t\tthis._lanes.set(record.laneId, record);\n\t\tconst suffix = /-(\\d+)$/.exec(record.laneId)?.[1];\n\t\tif (suffix) this.ensureCounterAtLeast(Number(suffix) + 1);\n\t\treturn { ...record };\n\t}\n\n\tmarkRunning(laneId: string): LaneRecord | undefined {\n\t\tconst record = this._lanes.get(laneId);\n\t\tif (!record || record.status !== \"queued\") return undefined;\n\t\tconst next = { ...record, status: \"running\" as const, startedAt: this._now() };\n\t\tthis._lanes.set(laneId, next);\n\t\treturn { ...next };\n\t}\n\n\tstart(args: { type: LaneType; goalId?: string; worktreeLaneKey?: string }): LaneRecord {\n\t\tconst record = this.enqueue(args);\n\t\treturn this.markRunning(record.laneId) as LaneRecord;\n\t}\n\n\tcomplete(\n\t\tlaneId: string,\n\t\targs: { status: LaneTerminalStatus; reasonCode?: string; costUsd?: number; evidenceEntryId?: string },\n\t): LaneRecord | undefined {\n\t\tconst record = this._lanes.get(laneId);\n\t\tif (!record || isLaneTerminalStatus(record.status)) return undefined;\n\t\tconst next: LaneRecord = {\n\t\t\t...record,\n\t\t\tstatus: args.status,\n\t\t\tcompletedAt: this._now(),\n\t\t};\n\t\tif (args.reasonCode !== undefined) next.reasonCode = args.reasonCode;\n\t\tif (args.costUsd !== undefined) next.costUsd = args.costUsd;\n\t\tif (args.evidenceEntryId !== undefined) next.evidenceEntryId = args.evidenceEntryId;\n\t\tthis._lanes.set(laneId, next);\n\t\tthis._evictOldTerminal();\n\t\treturn { ...next };\n\t}\n\n\tgetActiveCount(type?: LaneType): number {\n\t\tlet count = 0;\n\t\tfor (const record of this._lanes.values()) {\n\t\t\tif (isLaneTerminalStatus(record.status)) continue;\n\t\t\tif (type !== undefined && record.type !== type) continue;\n\t\t\tcount++;\n\t\t}\n\t\treturn count;\n\t}\n\n\tgetRunningCount(type?: LaneType): number {\n\t\tlet count = 0;\n\t\tfor (const record of this._lanes.values()) {\n\t\t\tif (record.status !== \"running\") continue;\n\t\t\tif (type !== undefined && record.type !== type) continue;\n\t\t\tcount++;\n\t\t}\n\t\treturn count;\n\t}\n\n\tgetRecords(): LaneRecord[] {\n\t\treturn [...this._lanes.values()].map((record) => ({ ...record }));\n\t}\n\n\tgetRecord(laneId: string): LaneRecord | undefined {\n\t\tconst record = this._lanes.get(laneId);\n\t\treturn record ? { ...record } : undefined;\n\t}\n}\n"]}
@@ -1,3 +1,2 @@
1
- import type { RiskAssessment, RiskAssessmentInput } from "./contracts.ts";
2
- export declare function assessOperationRisk(input: RiskAssessmentInput): RiskAssessment;
1
+ export { assessOperationRisk } from "../risk-classifier.ts";
3
2
  //# sourceMappingURL=risk-assessment.d.ts.map