@namzu/sdk 38.2.1 → 39.0.0

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 (493) hide show
  1. package/CHANGELOG.md +700 -0
  2. package/dist/advisory/executor.d.ts +10 -1
  3. package/dist/advisory/executor.d.ts.map +1 -1
  4. package/dist/advisory/executor.js +5 -26
  5. package/dist/advisory/executor.js.map +1 -1
  6. package/dist/advisory/history.d.ts +9 -0
  7. package/dist/advisory/history.d.ts.map +1 -0
  8. package/dist/advisory/history.js +120 -0
  9. package/dist/advisory/history.js.map +1 -0
  10. package/dist/advisory/index.d.ts +1 -1
  11. package/dist/advisory/index.d.ts.map +1 -1
  12. package/dist/advisory/index.js.map +1 -1
  13. package/dist/agents/ReactiveAgent.d.ts.map +1 -1
  14. package/dist/agents/ReactiveAgent.js +3 -0
  15. package/dist/agents/ReactiveAgent.js.map +1 -1
  16. package/dist/agents/runAgent.d.ts +10 -0
  17. package/dist/agents/runAgent.d.ts.map +1 -1
  18. package/dist/agents/runAgent.js +3 -0
  19. package/dist/agents/runAgent.js.map +1 -1
  20. package/dist/compaction/manual.d.ts +6 -0
  21. package/dist/compaction/manual.d.ts.map +1 -1
  22. package/dist/compaction/manual.js +21 -2
  23. package/dist/compaction/manual.js.map +1 -1
  24. package/dist/compaction/summary.d.ts.map +1 -1
  25. package/dist/compaction/summary.js +4 -1
  26. package/dist/compaction/summary.js.map +1 -1
  27. package/dist/config/runtime.js +2 -2
  28. package/dist/config/runtime.js.map +1 -1
  29. package/dist/contracts/schemas.js +1 -1
  30. package/dist/contracts/schemas.js.map +1 -1
  31. package/dist/eval/harness-protection.d.ts +18 -0
  32. package/dist/eval/harness-protection.d.ts.map +1 -0
  33. package/dist/eval/harness-protection.js +58 -0
  34. package/dist/eval/harness-protection.js.map +1 -0
  35. package/dist/eval/harness-verification.d.ts +6 -1
  36. package/dist/eval/harness-verification.d.ts.map +1 -1
  37. package/dist/eval/harness-verification.js +19 -2
  38. package/dist/eval/harness-verification.js.map +1 -1
  39. package/dist/eval/index.d.ts +1 -0
  40. package/dist/eval/index.d.ts.map +1 -1
  41. package/dist/eval/index.js.map +1 -1
  42. package/dist/manager/resident/activity.d.ts +50 -0
  43. package/dist/manager/resident/activity.d.ts.map +1 -0
  44. package/dist/manager/resident/activity.js +125 -0
  45. package/dist/manager/resident/activity.js.map +1 -0
  46. package/dist/manager/resident/agenda.d.ts +13 -1
  47. package/dist/manager/resident/agenda.d.ts.map +1 -1
  48. package/dist/manager/resident/agenda.js +40 -5
  49. package/dist/manager/resident/agenda.js.map +1 -1
  50. package/dist/manager/resident/consumption.d.ts +104 -0
  51. package/dist/manager/resident/consumption.d.ts.map +1 -0
  52. package/dist/manager/resident/consumption.js +233 -0
  53. package/dist/manager/resident/consumption.js.map +1 -0
  54. package/dist/manager/resident/evidence-recall.d.ts +24 -0
  55. package/dist/manager/resident/evidence-recall.d.ts.map +1 -0
  56. package/dist/manager/resident/evidence-recall.js +295 -0
  57. package/dist/manager/resident/evidence-recall.js.map +1 -0
  58. package/dist/manager/resident/history-disk.d.ts +10 -0
  59. package/dist/manager/resident/history-disk.d.ts.map +1 -0
  60. package/dist/manager/resident/history-disk.js +50 -0
  61. package/dist/manager/resident/history-disk.js.map +1 -0
  62. package/dist/manager/resident/history.d.ts +79 -0
  63. package/dist/manager/resident/history.d.ts.map +1 -0
  64. package/dist/manager/resident/history.js +203 -0
  65. package/dist/manager/resident/history.js.map +1 -0
  66. package/dist/manager/resident/initiative.d.ts.map +1 -1
  67. package/dist/manager/resident/initiative.js +11 -3
  68. package/dist/manager/resident/initiative.js.map +1 -1
  69. package/dist/manager/resident/learning-cycle.d.ts +131 -0
  70. package/dist/manager/resident/learning-cycle.d.ts.map +1 -0
  71. package/dist/manager/resident/learning-cycle.js +306 -0
  72. package/dist/manager/resident/learning-cycle.js.map +1 -0
  73. package/dist/manager/resident/learning-observation.d.ts +80 -0
  74. package/dist/manager/resident/learning-observation.d.ts.map +1 -0
  75. package/dist/manager/resident/learning-observation.js +22 -0
  76. package/dist/manager/resident/learning-observation.js.map +1 -0
  77. package/dist/manager/resident/learning-store.d.ts +106 -0
  78. package/dist/manager/resident/learning-store.d.ts.map +1 -0
  79. package/dist/manager/resident/learning-store.js +598 -0
  80. package/dist/manager/resident/learning-store.js.map +1 -0
  81. package/dist/manager/resident/learning.d.ts +246 -3
  82. package/dist/manager/resident/learning.d.ts.map +1 -1
  83. package/dist/manager/resident/learning.js +96 -6
  84. package/dist/manager/resident/learning.js.map +1 -1
  85. package/dist/manager/resident/outbox.d.ts +4 -4
  86. package/dist/manager/resident/store.d.ts +37 -4
  87. package/dist/manager/resident/store.d.ts.map +1 -1
  88. package/dist/manager/resident/store.js +27 -3
  89. package/dist/manager/resident/store.js.map +1 -1
  90. package/dist/manager/resident/tool-evidence.d.ts +71 -0
  91. package/dist/manager/resident/tool-evidence.d.ts.map +1 -0
  92. package/dist/manager/resident/tool-evidence.js +285 -0
  93. package/dist/manager/resident/tool-evidence.js.map +1 -0
  94. package/dist/manager/run/persistence.d.ts.map +1 -1
  95. package/dist/manager/run/persistence.js +6 -0
  96. package/dist/manager/run/persistence.js.map +1 -1
  97. package/dist/plugin/loader.d.ts.map +1 -1
  98. package/dist/plugin/loader.js +5 -3
  99. package/dist/plugin/loader.js.map +1 -1
  100. package/dist/prompt/coding-agent-doctrine.d.ts +1 -1
  101. package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -1
  102. package/dist/prompt/coding-agent-doctrine.js +2 -0
  103. package/dist/prompt/coding-agent-doctrine.js.map +1 -1
  104. package/dist/prompt/index.d.ts +2 -0
  105. package/dist/prompt/index.d.ts.map +1 -1
  106. package/dist/prompt/index.js +1 -0
  107. package/dist/prompt/index.js.map +1 -1
  108. package/dist/prompt/resident-learning.d.ts +19 -0
  109. package/dist/prompt/resident-learning.d.ts.map +1 -0
  110. package/dist/prompt/resident-learning.js +125 -0
  111. package/dist/prompt/resident-learning.js.map +1 -0
  112. package/dist/prompt/resident-step.d.ts +8 -1
  113. package/dist/prompt/resident-step.d.ts.map +1 -1
  114. package/dist/prompt/resident-step.js +65 -4
  115. package/dist/prompt/resident-step.js.map +1 -1
  116. package/dist/provider/collect-chat-completion.d.ts +2 -1
  117. package/dist/provider/collect-chat-completion.d.ts.map +1 -1
  118. package/dist/provider/collect-chat-completion.js +7 -6
  119. package/dist/provider/collect-chat-completion.js.map +1 -1
  120. package/dist/provider/fallback.d.ts.map +1 -1
  121. package/dist/provider/fallback.js +2 -1
  122. package/dist/provider/fallback.js.map +1 -1
  123. package/dist/provider/stream-text.d.ts +16 -0
  124. package/dist/provider/stream-text.d.ts.map +1 -0
  125. package/dist/provider/stream-text.js +51 -0
  126. package/dist/provider/stream-text.js.map +1 -0
  127. package/dist/public-runtime.d.ts +13 -3
  128. package/dist/public-runtime.d.ts.map +1 -1
  129. package/dist/public-runtime.js +12 -3
  130. package/dist/public-runtime.js.map +1 -1
  131. package/dist/public-tools.d.ts +2 -0
  132. package/dist/public-tools.d.ts.map +1 -1
  133. package/dist/public-tools.js +2 -0
  134. package/dist/public-tools.js.map +1 -1
  135. package/dist/public-types.d.ts +15 -3
  136. package/dist/public-types.d.ts.map +1 -1
  137. package/dist/run/LimitChecker.js +3 -3
  138. package/dist/run/LimitChecker.js.map +1 -1
  139. package/dist/run/evidence-query.d.ts +41 -0
  140. package/dist/run/evidence-query.d.ts.map +1 -0
  141. package/dist/run/evidence-query.js +270 -0
  142. package/dist/run/evidence-query.js.map +1 -0
  143. package/dist/run/evidence-recall.d.ts +99 -0
  144. package/dist/run/evidence-recall.d.ts.map +1 -0
  145. package/dist/run/evidence-recall.js +633 -0
  146. package/dist/run/evidence-recall.js.map +1 -0
  147. package/dist/run/index.d.ts +2 -0
  148. package/dist/run/index.d.ts.map +1 -1
  149. package/dist/run/index.js +1 -0
  150. package/dist/run/index.js.map +1 -1
  151. package/dist/run/json-claim-verifier.d.ts +83 -0
  152. package/dist/run/json-claim-verifier.d.ts.map +1 -0
  153. package/dist/run/json-claim-verifier.js +200 -0
  154. package/dist/run/json-claim-verifier.js.map +1 -0
  155. package/dist/run/preparation-context-error.d.ts +10 -0
  156. package/dist/run/preparation-context-error.d.ts.map +1 -0
  157. package/dist/run/preparation-context-error.js +15 -0
  158. package/dist/run/preparation-context-error.js.map +1 -0
  159. package/dist/run-query/index.d.ts +3 -1
  160. package/dist/run-query/index.d.ts.map +1 -1
  161. package/dist/runtime/query/callback-inference.d.ts +8 -0
  162. package/dist/runtime/query/callback-inference.d.ts.map +1 -0
  163. package/dist/runtime/query/callback-inference.js +89 -0
  164. package/dist/runtime/query/callback-inference.js.map +1 -0
  165. package/dist/runtime/query/checkpoint.d.ts +4 -0
  166. package/dist/runtime/query/checkpoint.d.ts.map +1 -1
  167. package/dist/runtime/query/checkpoint.js +13 -0
  168. package/dist/runtime/query/checkpoint.js.map +1 -1
  169. package/dist/runtime/query/events.d.ts +1 -0
  170. package/dist/runtime/query/events.d.ts.map +1 -1
  171. package/dist/runtime/query/events.js +18 -0
  172. package/dist/runtime/query/events.js.map +1 -1
  173. package/dist/runtime/query/executor.d.ts +7 -1
  174. package/dist/runtime/query/executor.d.ts.map +1 -1
  175. package/dist/runtime/query/executor.js +38 -7
  176. package/dist/runtime/query/executor.js.map +1 -1
  177. package/dist/runtime/query/file-evidence-context.d.ts +5 -0
  178. package/dist/runtime/query/file-evidence-context.d.ts.map +1 -0
  179. package/dist/runtime/query/file-evidence-context.js +64 -0
  180. package/dist/runtime/query/file-evidence-context.js.map +1 -0
  181. package/dist/runtime/query/guard.d.ts.map +1 -1
  182. package/dist/runtime/query/guard.js +4 -0
  183. package/dist/runtime/query/guard.js.map +1 -1
  184. package/dist/runtime/query/index.d.ts +10 -1
  185. package/dist/runtime/query/index.d.ts.map +1 -1
  186. package/dist/runtime/query/index.js +39 -24
  187. package/dist/runtime/query/index.js.map +1 -1
  188. package/dist/runtime/query/iteration/index.d.ts +9 -31
  189. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  190. package/dist/runtime/query/iteration/index.js +231 -93
  191. package/dist/runtime/query/iteration/index.js.map +1 -1
  192. package/dist/runtime/query/iteration/phases/advisory.d.ts +2 -1
  193. package/dist/runtime/query/iteration/phases/advisory.d.ts.map +1 -1
  194. package/dist/runtime/query/iteration/phases/advisory.js +2 -1
  195. package/dist/runtime/query/iteration/phases/advisory.js.map +1 -1
  196. package/dist/runtime/query/iteration/phases/context.d.ts +2 -1
  197. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  198. package/dist/runtime/query/iteration/phases/context.js.map +1 -1
  199. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  200. package/dist/runtime/query/iteration/phases/tool-review.js +3 -0
  201. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  202. package/dist/runtime/query/iteration/provider-rejected-image.d.ts +2 -1
  203. package/dist/runtime/query/iteration/provider-rejected-image.d.ts.map +1 -1
  204. package/dist/runtime/query/iteration/provider-rejected-image.js +5 -2
  205. package/dist/runtime/query/iteration/provider-rejected-image.js.map +1 -1
  206. package/dist/runtime/query/iteration/stream-turn.d.ts +4 -1
  207. package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
  208. package/dist/runtime/query/iteration/stream-turn.js +22 -8
  209. package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
  210. package/dist/runtime/query/resume-pending.d.ts +18 -33
  211. package/dist/runtime/query/resume-pending.d.ts.map +1 -1
  212. package/dist/runtime/query/resume-pending.js +59 -42
  213. package/dist/runtime/query/resume-pending.js.map +1 -1
  214. package/dist/runtime/query/review-policy.d.ts +4 -4
  215. package/dist/runtime/query/review-policy.d.ts.map +1 -1
  216. package/dist/runtime/query/review-policy.js +10 -9
  217. package/dist/runtime/query/review-policy.js.map +1 -1
  218. package/dist/runtime/query/sandbox-lifecycle.d.ts.map +1 -1
  219. package/dist/runtime/query/sandbox-lifecycle.js +4 -0
  220. package/dist/runtime/query/sandbox-lifecycle.js.map +1 -1
  221. package/dist/runtime/query/tool-output-budget.d.ts +10 -6
  222. package/dist/runtime/query/tool-output-budget.d.ts.map +1 -1
  223. package/dist/runtime/query/tool-output-budget.js +54 -12
  224. package/dist/runtime/query/tool-output-budget.js.map +1 -1
  225. package/dist/runtime/query/tooling.d.ts +3 -1
  226. package/dist/runtime/query/tooling.d.ts.map +1 -1
  227. package/dist/runtime/query/tooling.js +4 -0
  228. package/dist/runtime/query/tooling.js.map +1 -1
  229. package/dist/scheduler/completion-inbox.d.ts +3 -0
  230. package/dist/scheduler/completion-inbox.d.ts.map +1 -1
  231. package/dist/scheduler/completion-inbox.js +28 -0
  232. package/dist/scheduler/completion-inbox.js.map +1 -1
  233. package/dist/store/evidence/compaction-archive.d.ts +109 -0
  234. package/dist/store/evidence/compaction-archive.d.ts.map +1 -0
  235. package/dist/store/evidence/compaction-archive.js +125 -0
  236. package/dist/store/evidence/compaction-archive.js.map +1 -0
  237. package/dist/store/evidence/compaction-provenance.d.ts +7 -0
  238. package/dist/store/evidence/compaction-provenance.d.ts.map +1 -0
  239. package/dist/store/evidence/compaction-provenance.js +49 -0
  240. package/dist/store/evidence/compaction-provenance.js.map +1 -0
  241. package/dist/store/evidence/compaction-text.d.ts +16 -0
  242. package/dist/store/evidence/compaction-text.d.ts.map +1 -0
  243. package/dist/store/evidence/compaction-text.js +51 -0
  244. package/dist/store/evidence/compaction-text.js.map +1 -0
  245. package/dist/store/evidence/disk.d.ts +11 -0
  246. package/dist/store/evidence/disk.d.ts.map +1 -0
  247. package/dist/store/evidence/disk.js +367 -0
  248. package/dist/store/evidence/disk.js.map +1 -0
  249. package/dist/store/evidence/format.d.ts +25 -0
  250. package/dist/store/evidence/format.d.ts.map +1 -0
  251. package/dist/store/evidence/format.js +115 -0
  252. package/dist/store/evidence/format.js.map +1 -0
  253. package/dist/store/evidence/index-page.d.ts +208 -0
  254. package/dist/store/evidence/index-page.d.ts.map +1 -0
  255. package/dist/store/evidence/index-page.js +262 -0
  256. package/dist/store/evidence/index-page.js.map +1 -0
  257. package/dist/store/evidence/io.d.ts +24 -0
  258. package/dist/store/evidence/io.d.ts.map +1 -0
  259. package/dist/store/evidence/io.js +69 -0
  260. package/dist/store/evidence/io.js.map +1 -0
  261. package/dist/store/evidence/linked.d.ts +9 -0
  262. package/dist/store/evidence/linked.d.ts.map +1 -0
  263. package/dist/store/evidence/linked.js +314 -0
  264. package/dist/store/evidence/linked.js.map +1 -0
  265. package/dist/store/evidence/passages.d.ts +15 -0
  266. package/dist/store/evidence/passages.d.ts.map +1 -0
  267. package/dist/store/evidence/passages.js +72 -0
  268. package/dist/store/evidence/passages.js.map +1 -0
  269. package/dist/store/evidence/record-chain.d.ts +42 -0
  270. package/dist/store/evidence/record-chain.d.ts.map +1 -0
  271. package/dist/store/evidence/record-chain.js +111 -0
  272. package/dist/store/evidence/record-chain.js.map +1 -0
  273. package/dist/store/evidence/search-input.d.ts +21 -0
  274. package/dist/store/evidence/search-input.d.ts.map +1 -0
  275. package/dist/store/evidence/search-input.js +44 -0
  276. package/dist/store/evidence/search-input.js.map +1 -0
  277. package/dist/store/evidence/selection.d.ts +9 -0
  278. package/dist/store/evidence/selection.d.ts.map +1 -0
  279. package/dist/store/evidence/selection.js +17 -0
  280. package/dist/store/evidence/selection.js.map +1 -0
  281. package/dist/store/evidence/source-kind.d.ts +11 -0
  282. package/dist/store/evidence/source-kind.d.ts.map +1 -0
  283. package/dist/store/evidence/source-kind.js +26 -0
  284. package/dist/store/evidence/source-kind.js.map +1 -0
  285. package/dist/store/evidence/source-text.d.ts +51 -0
  286. package/dist/store/evidence/source-text.d.ts.map +1 -0
  287. package/dist/store/evidence/source-text.js +213 -0
  288. package/dist/store/evidence/source-text.js.map +1 -0
  289. package/dist/store/evidence/types.d.ts +162 -0
  290. package/dist/store/evidence/types.d.ts.map +1 -0
  291. package/dist/store/evidence/types.js +2 -0
  292. package/dist/store/evidence/types.js.map +1 -0
  293. package/dist/store/memory/disk.d.ts +2 -0
  294. package/dist/store/memory/disk.d.ts.map +1 -1
  295. package/dist/store/memory/disk.js +2 -1
  296. package/dist/store/memory/disk.js.map +1 -1
  297. package/dist/store/run/disk.d.ts +10 -0
  298. package/dist/store/run/disk.d.ts.map +1 -1
  299. package/dist/store/run/disk.js +87 -7
  300. package/dist/store/run/disk.js.map +1 -1
  301. package/dist/store/run/memory.d.ts +1 -0
  302. package/dist/store/run/memory.d.ts.map +1 -1
  303. package/dist/store/run/memory.js +10 -0
  304. package/dist/store/run/memory.js.map +1 -1
  305. package/dist/store/run/tool-executions.d.ts +13 -0
  306. package/dist/store/run/tool-executions.d.ts.map +1 -0
  307. package/dist/store/run/tool-executions.js +99 -0
  308. package/dist/store/run/tool-executions.js.map +1 -0
  309. package/dist/store/session/index.d.ts +2 -0
  310. package/dist/store/session/index.d.ts.map +1 -1
  311. package/dist/store/session/index.js +1 -0
  312. package/dist/store/session/index.js.map +1 -1
  313. package/dist/store/session/sqlite.d.ts +57 -0
  314. package/dist/store/session/sqlite.d.ts.map +1 -0
  315. package/dist/store/session/sqlite.js +430 -0
  316. package/dist/store/session/sqlite.js.map +1 -0
  317. package/dist/tools/builtins/job.d.ts.map +1 -1
  318. package/dist/tools/builtins/job.js +4 -5
  319. package/dist/tools/builtins/job.js.map +1 -1
  320. package/dist/tools/builtins/write-file.js +2 -2
  321. package/dist/tools/builtins/write-file.js.map +1 -1
  322. package/dist/tools/defineTool.d.ts +2 -1
  323. package/dist/tools/defineTool.d.ts.map +1 -1
  324. package/dist/tools/defineTool.js +1 -1
  325. package/dist/tools/defineTool.js.map +1 -1
  326. package/dist/tools/file-read-tracker.d.ts.map +1 -1
  327. package/dist/tools/file-read-tracker.js +12 -3
  328. package/dist/tools/file-read-tracker.js.map +1 -1
  329. package/dist/tools/resident-history.d.ts +10 -0
  330. package/dist/tools/resident-history.d.ts.map +1 -0
  331. package/dist/tools/resident-history.js +80 -0
  332. package/dist/tools/resident-history.js.map +1 -0
  333. package/dist/tools/resident-tool-evidence.d.ts +5 -0
  334. package/dist/tools/resident-tool-evidence.d.ts.map +1 -0
  335. package/dist/tools/resident-tool-evidence.js +57 -0
  336. package/dist/tools/resident-tool-evidence.js.map +1 -0
  337. package/dist/types/advisory/config.d.ts +7 -0
  338. package/dist/types/advisory/config.d.ts.map +1 -1
  339. package/dist/types/agent/reactive.d.ts +1 -0
  340. package/dist/types/agent/reactive.d.ts.map +1 -1
  341. package/dist/types/authorization/index.d.ts +9 -9
  342. package/dist/types/authorization/index.d.ts.map +1 -1
  343. package/dist/types/authorization/index.js +1 -1
  344. package/dist/types/authorization/index.js.map +1 -1
  345. package/dist/types/hitl/index.d.ts +4 -0
  346. package/dist/types/hitl/index.d.ts.map +1 -1
  347. package/dist/types/hitl/index.js.map +1 -1
  348. package/dist/types/message/index.d.ts +16 -2
  349. package/dist/types/message/index.d.ts.map +1 -1
  350. package/dist/types/message/index.js +8 -1
  351. package/dist/types/message/index.js.map +1 -1
  352. package/dist/types/provider/chat.d.ts +2 -0
  353. package/dist/types/provider/chat.d.ts.map +1 -1
  354. package/dist/types/provider/stream.d.ts +4 -0
  355. package/dist/types/provider/stream.d.ts.map +1 -1
  356. package/dist/types/run/answer-review.d.ts +34 -3
  357. package/dist/types/run/answer-review.d.ts.map +1 -1
  358. package/dist/types/run/config.d.ts +3 -0
  359. package/dist/types/run/config.d.ts.map +1 -1
  360. package/dist/types/run/entity.d.ts +7 -0
  361. package/dist/types/run/entity.d.ts.map +1 -1
  362. package/dist/types/run/events.d.ts +31 -8
  363. package/dist/types/run/events.d.ts.map +1 -1
  364. package/dist/types/run/events.js.map +1 -1
  365. package/dist/types/run/prepare-step.d.ts +53 -8
  366. package/dist/types/run/prepare-step.d.ts.map +1 -1
  367. package/dist/types/run/store.d.ts +29 -4
  368. package/dist/types/run/store.d.ts.map +1 -1
  369. package/dist/types/run/store.js +0 -28
  370. package/dist/types/run/store.js.map +1 -1
  371. package/dist/types/tool/index.d.ts +15 -1
  372. package/dist/types/tool/index.d.ts.map +1 -1
  373. package/dist/types/tool/index.js.map +1 -1
  374. package/dist/utils/await-with-abort.d.ts +8 -0
  375. package/dist/utils/await-with-abort.d.ts.map +1 -0
  376. package/dist/utils/await-with-abort.js +28 -0
  377. package/dist/utils/await-with-abort.js.map +1 -0
  378. package/dist/utils/evidence-time.d.ts +3 -0
  379. package/dist/utils/evidence-time.d.ts.map +1 -0
  380. package/dist/utils/evidence-time.js +10 -0
  381. package/dist/utils/evidence-time.js.map +1 -0
  382. package/dist/utils/evidence-tokens.d.ts +13 -0
  383. package/dist/utils/evidence-tokens.d.ts.map +1 -0
  384. package/dist/utils/evidence-tokens.js +29 -0
  385. package/dist/utils/evidence-tokens.js.map +1 -0
  386. package/package.json +1 -1
  387. package/src/advisory/executor.ts +15 -30
  388. package/src/advisory/history.ts +126 -0
  389. package/src/advisory/index.ts +5 -1
  390. package/src/agents/ReactiveAgent.ts +3 -0
  391. package/src/agents/runAgent.ts +14 -1
  392. package/src/compaction/manual.ts +30 -2
  393. package/src/compaction/summary.ts +4 -1
  394. package/src/config/runtime.ts +2 -2
  395. package/src/contracts/schemas.ts +1 -1
  396. package/src/eval/harness-protection.ts +79 -0
  397. package/src/eval/harness-verification.ts +31 -1
  398. package/src/eval/index.ts +1 -0
  399. package/src/manager/resident/activity.ts +187 -0
  400. package/src/manager/resident/agenda.ts +59 -5
  401. package/src/manager/resident/consumption.ts +311 -0
  402. package/src/manager/resident/evidence-recall.ts +363 -0
  403. package/src/manager/resident/history-disk.ts +63 -0
  404. package/src/manager/resident/history.ts +312 -0
  405. package/src/manager/resident/initiative.ts +13 -3
  406. package/src/manager/resident/learning-cycle.ts +499 -0
  407. package/src/manager/resident/learning-observation.ts +39 -0
  408. package/src/manager/resident/learning-store.ts +813 -0
  409. package/src/manager/resident/learning.ts +132 -8
  410. package/src/manager/resident/store.ts +31 -3
  411. package/src/manager/resident/tool-evidence.ts +412 -0
  412. package/src/manager/run/persistence.ts +6 -0
  413. package/src/plugin/loader.ts +8 -3
  414. package/src/prompt/coding-agent-doctrine.ts +2 -0
  415. package/src/prompt/index.ts +2 -0
  416. package/src/prompt/resident-learning.ts +143 -0
  417. package/src/prompt/resident-step.ts +83 -3
  418. package/src/provider/collect-chat-completion.ts +7 -6
  419. package/src/provider/fallback.ts +2 -1
  420. package/src/provider/stream-text.ts +56 -0
  421. package/src/public-runtime.ts +30 -0
  422. package/src/public-tools.ts +3 -0
  423. package/src/public-types.ts +98 -0
  424. package/src/run/LimitChecker.ts +3 -3
  425. package/src/run/evidence-query.ts +333 -0
  426. package/src/run/evidence-recall.ts +854 -0
  427. package/src/run/index.ts +11 -0
  428. package/src/run/json-claim-verifier.ts +298 -0
  429. package/src/run/preparation-context-error.ts +16 -0
  430. package/src/run-query/index.ts +1 -1
  431. package/src/runtime/query/callback-inference.ts +94 -0
  432. package/src/runtime/query/checkpoint.ts +14 -0
  433. package/src/runtime/query/events.ts +22 -0
  434. package/src/runtime/query/executor.ts +51 -9
  435. package/src/runtime/query/file-evidence-context.ts +65 -0
  436. package/src/runtime/query/guard.ts +2 -0
  437. package/src/runtime/query/index.ts +49 -25
  438. package/src/runtime/query/iteration/index.ts +269 -86
  439. package/src/runtime/query/iteration/phases/advisory.ts +3 -0
  440. package/src/runtime/query/iteration/phases/context.ts +2 -0
  441. package/src/runtime/query/iteration/phases/tool-review.ts +3 -0
  442. package/src/runtime/query/iteration/provider-rejected-image.ts +6 -1
  443. package/src/runtime/query/iteration/stream-turn.ts +35 -8
  444. package/src/runtime/query/resume-pending.ts +65 -40
  445. package/src/runtime/query/review-policy.ts +13 -9
  446. package/src/runtime/query/sandbox-lifecycle.ts +3 -0
  447. package/src/runtime/query/tool-output-budget.ts +65 -13
  448. package/src/runtime/query/tooling.ts +7 -1
  449. package/src/scheduler/completion-inbox.ts +26 -0
  450. package/src/store/evidence/compaction-archive.ts +139 -0
  451. package/src/store/evidence/compaction-provenance.ts +52 -0
  452. package/src/store/evidence/compaction-text.ts +61 -0
  453. package/src/store/evidence/disk.ts +461 -0
  454. package/src/store/evidence/format.ts +126 -0
  455. package/src/store/evidence/index-page.ts +292 -0
  456. package/src/store/evidence/io.ts +95 -0
  457. package/src/store/evidence/linked.ts +365 -0
  458. package/src/store/evidence/passages.ts +88 -0
  459. package/src/store/evidence/record-chain.ts +108 -0
  460. package/src/store/evidence/search-input.ts +62 -0
  461. package/src/store/evidence/selection.ts +25 -0
  462. package/src/store/evidence/source-kind.ts +36 -0
  463. package/src/store/evidence/source-text.ts +285 -0
  464. package/src/store/evidence/types.ts +177 -0
  465. package/src/store/memory/disk.ts +4 -1
  466. package/src/store/run/disk.ts +110 -8
  467. package/src/store/run/memory.ts +10 -0
  468. package/src/store/run/tool-executions.ts +112 -0
  469. package/src/store/session/index.ts +2 -0
  470. package/src/store/session/sqlite.ts +584 -0
  471. package/src/tools/builtins/job.ts +4 -5
  472. package/src/tools/builtins/write-file.ts +2 -2
  473. package/src/tools/defineTool.ts +4 -2
  474. package/src/tools/file-read-tracker.ts +8 -2
  475. package/src/tools/resident-history.ts +86 -0
  476. package/src/tools/resident-tool-evidence.ts +68 -0
  477. package/src/types/advisory/config.ts +7 -0
  478. package/src/types/agent/reactive.ts +1 -0
  479. package/src/types/authorization/index.ts +2 -2
  480. package/src/types/hitl/index.ts +4 -0
  481. package/src/types/message/index.ts +20 -0
  482. package/src/types/provider/chat.ts +2 -0
  483. package/src/types/provider/stream.ts +4 -0
  484. package/src/types/run/answer-review.ts +34 -3
  485. package/src/types/run/config.ts +3 -0
  486. package/src/types/run/entity.ts +7 -0
  487. package/src/types/run/events.ts +31 -8
  488. package/src/types/run/prepare-step.ts +59 -8
  489. package/src/types/run/store.ts +35 -4
  490. package/src/types/tool/index.ts +19 -1
  491. package/src/utils/await-with-abort.ts +26 -0
  492. package/src/utils/evidence-time.ts +9 -0
  493. package/src/utils/evidence-tokens.ts +32 -0
@@ -0,0 +1,461 @@
1
+ import { lstat } from 'node:fs/promises'
2
+ import type { FileHandle } from 'node:fs/promises'
3
+ import { join, resolve } from 'node:path'
4
+ import { z } from 'zod'
5
+ import { EVIDENCE_CHUNK_BYTES, digest, mayContain, mayContainToken } from './format.js'
6
+ import {
7
+ type EvidenceSeal,
8
+ entrySchema,
9
+ evidenceSeal,
10
+ indexPage,
11
+ positionSchema,
12
+ } from './index-page.js'
13
+ import {
14
+ type EvidenceBudget,
15
+ EvidencePageLimit,
16
+ PAGE_BYTES,
17
+ RECORD_BYTES,
18
+ decode,
19
+ openEvidence,
20
+ readBytes,
21
+ readSmall,
22
+ stamp,
23
+ } from './io.js'
24
+ import { passageMatcher, passagesInWindow } from './passages.js'
25
+ import { evidenceSearchInput, evidenceTermRefinement, evidenceTermsSchema } from './search-input.js'
26
+ import {
27
+ evidenceExclusionsKey,
28
+ evidenceExclusionsSchema,
29
+ excludesSuccessfulTool,
30
+ } from './selection.js'
31
+ import { createTextSourceReader, readTextPage } from './source-text.js'
32
+ import type {
33
+ DiskRunEvidenceOptions,
34
+ RunEvidenceReadOptions,
35
+ RunEvidenceReadResult,
36
+ RunEvidenceSource,
37
+ RunTextEvidenceMatch,
38
+ RunTextEvidenceReadResult,
39
+ RunTextEvidenceSearchOptions,
40
+ RunTextEvidenceSource,
41
+ } from './types.js'
42
+
43
+ const integer = z.number().int().nonnegative().safe()
44
+ const scopeSchema = z
45
+ .object({
46
+ tenantId: z.string().uuid(),
47
+ projectId: z.string().uuid(),
48
+ sessionId: z.string().uuid(),
49
+ runId: z.string().uuid(),
50
+ })
51
+ .strict()
52
+ const cursorSchema = z.object({
53
+ kind: z.enum(['search', 'search-terms', 'search-tokens']),
54
+ query: z.string().max(256),
55
+ termsKey: z
56
+ .string()
57
+ .regex(/^[a-f0-9]{64}$/)
58
+ .optional(),
59
+ caseSensitive: z.boolean().default(true),
60
+ matchMode: z.enum(['literal', 'token']).default('literal'),
61
+ exclusionsKey: z
62
+ .string()
63
+ .regex(/^[a-f0-9]{64}$/)
64
+ .optional(),
65
+ seq: integer.optional(),
66
+ part: integer.optional(),
67
+ mode: z.enum(['tools', 'text']).default('tools'),
68
+ position: positionSchema,
69
+ entry: integer.max(64),
70
+ chunk: integer,
71
+ within: integer.default(0),
72
+ })
73
+ const pointerSchema = entrySchema.pick({
74
+ offset: true,
75
+ length: true,
76
+ sha256: true,
77
+ seq: true,
78
+ part: true,
79
+ })
80
+ const addressSchema = z.object({ kind: z.literal('text'), entry: pointerSchema })
81
+
82
+ /** Ignore an uncommitted tail in a nonterminal snapshot without repairing the writer's file. */
83
+ async function completePrefix(handle: FileHandle, size: number, budget: EvidenceBudget) {
84
+ if ((await readBytes(handle, size - 1, 1, budget))[0] === 10) return size
85
+ const floor = Math.max(0, size - RECORD_BYTES)
86
+ let end = size - 1
87
+ while (end > floor) {
88
+ const start = Math.max(floor, end - 65_536)
89
+ const bytes = await readBytes(handle, start, end - start, budget)
90
+ const newline = bytes.lastIndexOf(10)
91
+ if (newline >= 0) return start + newline + 1
92
+ end = start
93
+ }
94
+ if (floor === 0) throw new Error('Transcript has no complete recorded evidence.')
95
+ throw new Error('Incomplete transcript tail exceeds the bounded record size.')
96
+ }
97
+ /**
98
+ * @experimental Bounded, authenticated disk index over one explicitly authorized run.
99
+ * Closed by default; snapshot mode permits nonterminal metadata without assuming a dead writer.
100
+ * The host owns authorization and the private directories. Stat changes invalidate addresses;
101
+ * individual record/chunk digests detect changed bytes. This is not a hostile filesystem sandbox.
102
+ */
103
+ export function createDiskRunTextEvidenceSource(
104
+ options: DiskRunEvidenceOptions,
105
+ ): RunTextEvidenceSource {
106
+ return createSource(options, 'text')
107
+ }
108
+
109
+ /** @experimental Tool-only view of the shared invocation text index. */
110
+ export function createDiskRunEvidenceSource(options: DiskRunEvidenceOptions): RunEvidenceSource {
111
+ const source = createSource(options, 'tools')
112
+ const tool = <T extends { toolName?: string; isError?: boolean }>(value: T) => {
113
+ if (value.toolName === undefined || value.isError === undefined)
114
+ throw new Error('Expected tool evidence.')
115
+ return { ...value, toolName: value.toolName, isError: value.isError }
116
+ }
117
+ return Object.freeze({
118
+ scope: source.scope,
119
+ supportsTermRefinement: true,
120
+ async search(options: RunTextEvidenceSearchOptions = {}, signal?: AbortSignal) {
121
+ const result = await source.search(options, signal)
122
+ return { ...result, matches: result.matches.map(tool) }
123
+ },
124
+ async read(
125
+ options: RunEvidenceReadOptions,
126
+ signal?: AbortSignal,
127
+ ): Promise<RunEvidenceReadResult> {
128
+ return tool(await source.read(options, signal))
129
+ },
130
+ })
131
+ }
132
+
133
+ function createSource(
134
+ options: DiskRunEvidenceOptions,
135
+ mode: 'tools' | 'text',
136
+ ): RunTextEvidenceSource {
137
+ const consistency = z.enum(['closed', 'snapshot']).parse(options.consistency ?? 'closed')
138
+ const maxReadBytes = z
139
+ .number()
140
+ .int()
141
+ .min(1024 * 1024)
142
+ .max(PAGE_BYTES)
143
+ .parse(options.maxReadBytes ?? PAGE_BYTES)
144
+ const scope = Object.freeze(scopeSchema.parse(options.scope))
145
+ const runDir = resolve(options.runDir)
146
+ const indexDir = resolve(options.indexDir)
147
+ const scopeKey = digest(JSON.stringify(scope))
148
+ async function access<T>(
149
+ signal: AbortSignal | undefined,
150
+ requestedBytes: number | undefined,
151
+ action: (
152
+ handle: FileHandle,
153
+ size: number,
154
+ seal: EvidenceSeal,
155
+ sourceKey: string,
156
+ budget: EvidenceBudget,
157
+ nonterminal: boolean,
158
+ ) => Promise<T>,
159
+ ): Promise<T> {
160
+ const budget: EvidenceBudget = {
161
+ bytes: 0,
162
+ limit: Math.min(maxReadBytes, requestedBytes ?? maxReadBytes),
163
+ signal,
164
+ }
165
+ signal?.throwIfAborted()
166
+ const metaPath = join(runDir, 'run.json')
167
+ const metaStamp = stamp(await lstat(metaPath))
168
+ const metaBytes = await readSmall(metaPath, budget, 512 * 1024)
169
+ if (metaStamp !== stamp(await lstat(metaPath)))
170
+ throw new Error('Run metadata changed during retrieval.')
171
+ const meta = JSON.parse(decode(metaBytes))
172
+ const terminal = ['completed', 'failed', 'cancelled'].includes(meta.status)
173
+ const readable =
174
+ terminal ||
175
+ (consistency === 'snapshot' && ['idle', 'pending', 'running'].includes(meta.status))
176
+ if (
177
+ meta.id !== scope.runId ||
178
+ !readable ||
179
+ JSON.stringify(scopeSchema.parse(meta.metadata?.scope)) !== JSON.stringify(scope)
180
+ )
181
+ throw new Error(
182
+ consistency === 'closed'
183
+ ? 'Evidence run is not closed or does not belong to the authorized scope.'
184
+ : 'Evidence run does not satisfy snapshot consistency or its authorized scope.',
185
+ )
186
+ const path = join(runDir, 'transcript.jsonl')
187
+ const handle = await openEvidence(path)
188
+ try {
189
+ const before = await handle.stat()
190
+ if (before.size === 0) throw new Error('Transcript is empty; evidence is incomplete.')
191
+ const size =
192
+ consistency === 'snapshot' && !terminal
193
+ ? await completePrefix(handle, before.size, budget)
194
+ : before.size
195
+ const sourceKey = digest(
196
+ `${consistency === 'snapshot' ? 'snapshot-v1:' : ''}${mode === 'text' ? 'text-v2:' : ''}${scopeKey}:${stamp(before)}:${digest(metaBytes)}`,
197
+ )
198
+ const seal = await evidenceSeal(indexDir, scopeKey, sourceKey, budget)
199
+ const value = await action(handle, size, seal, sourceKey, budget, !terminal)
200
+ signal?.throwIfAborted()
201
+ if (
202
+ stamp(before) !== stamp(await handle.stat()) ||
203
+ stamp(before) !== stamp(await lstat(path)) ||
204
+ metaStamp !== stamp(await lstat(metaPath))
205
+ )
206
+ throw new Error('Evidence source changed during retrieval.')
207
+ return value
208
+ } finally {
209
+ await handle.close()
210
+ }
211
+ }
212
+ return Object.freeze({
213
+ scope,
214
+ supportsTermRefinement: true,
215
+ async search(options: RunTextEvidenceSearchOptions = {}, signal?: AbortSignal) {
216
+ const input = z
217
+ .object({
218
+ maxReadBytes: integer
219
+ .min(1024 * 1024)
220
+ .max(PAGE_BYTES)
221
+ .optional(),
222
+ query: z.string().max(256).optional(),
223
+ terms: evidenceTermsSchema,
224
+ refineTerms: evidenceTermsSchema,
225
+ caseSensitive: z.boolean().default(true),
226
+ matchMode: z.enum(['literal', 'token']).default('literal'),
227
+ excludeSuccessfulTools: evidenceExclusionsSchema,
228
+ excludeDerivedSummaries: z.boolean().default(false),
229
+ cursor: z.string().max(4096).optional(),
230
+ seq: integer.positive().optional(),
231
+ part: integer.optional(),
232
+ limit: integer.min(1).max(4).default(4),
233
+ })
234
+ .strict()
235
+ .parse(options)
236
+ if (input.part !== undefined && input.seq === undefined)
237
+ throw new Error('Part requires an event sequence.')
238
+ const { query, terms, termsKey, browse } = evidenceSearchInput(input)
239
+ const refined = input.refineTerms
240
+ ? evidenceSearchInput({
241
+ terms: evidenceTermRefinement(input, input.refineTerms),
242
+ matchMode: 'token',
243
+ })
244
+ : undefined
245
+ const selectedTerms = refined?.terms ?? terms
246
+ const exclusionsKey = evidenceExclusionsKey(
247
+ input.excludeSuccessfulTools,
248
+ input.excludeDerivedSummaries,
249
+ )
250
+ const kind =
251
+ input.matchMode === 'token'
252
+ ? ('search-tokens' as const)
253
+ : terms
254
+ ? ('search-terms' as const)
255
+ : ('search' as const)
256
+ return access(
257
+ signal,
258
+ input.maxReadBytes,
259
+ async (handle, size, seal, sourceKey, budget, nonterminal) => {
260
+ const readSource = createTextSourceReader(handle, runDir, scope.runId, budget)
261
+ const cursor = input.cursor
262
+ ? cursorSchema.parse(seal.unpack(input.cursor))
263
+ : {
264
+ kind,
265
+ query,
266
+ termsKey,
267
+ exclusionsKey,
268
+ seq: input.seq,
269
+ part: input.part,
270
+ mode,
271
+ position: { offset: 0, seq: 0, textIndex: 0 },
272
+ entry: 0,
273
+ chunk: 0,
274
+ within: 0,
275
+ caseSensitive: input.caseSensitive,
276
+ matchMode: input.matchMode,
277
+ }
278
+ if (
279
+ cursor.kind !== kind ||
280
+ cursor.query !== query ||
281
+ cursor.termsKey !== termsKey ||
282
+ cursor.exclusionsKey !== exclusionsKey ||
283
+ cursor.caseSensitive !== input.caseSensitive ||
284
+ cursor.matchMode !== input.matchMode ||
285
+ cursor.seq !== input.seq ||
286
+ cursor.part !== input.part ||
287
+ cursor.mode !== mode
288
+ )
289
+ throw new Error('Search cursor query changed.')
290
+ // Authenticate the original query first, then seal future cursors
291
+ // with the narrower key at exactly the same archive position.
292
+ if (refined) cursor.termsKey = refined.termsKey
293
+ const { page, cacheHit } = await indexPage(
294
+ handle,
295
+ size,
296
+ scope.runId,
297
+ cursor.position,
298
+ seal,
299
+ sourceKey,
300
+ budget,
301
+ )
302
+ const matches: RunTextEvidenceMatch[] = []
303
+ const unavailable: string[] = []
304
+ let partial = false
305
+ let excludedToolResults = 0
306
+ let excludedSummaries = 0
307
+ let entryIndex = cursor.entry
308
+ let chunk = cursor.chunk
309
+ let within = cursor.within
310
+ const matchPassage = passageMatcher(
311
+ selectedTerms ?? query,
312
+ input.caseSensitive,
313
+ input.matchMode,
314
+ )
315
+ while (entryIndex < page.entries.length && matches.length < input.limit) {
316
+ const entry = page.entries[entryIndex]
317
+ if (!entry) throw new Error('Invalid index entry.')
318
+ if (
319
+ (mode === 'tools' && entry.source !== 'tool_completed') ||
320
+ (input.seq !== undefined && entry.seq !== input.seq) ||
321
+ (input.part !== undefined && entry.part !== input.part)
322
+ ) {
323
+ entryIndex++
324
+ chunk = 0
325
+ within = 0
326
+ continue
327
+ }
328
+ try {
329
+ const derived =
330
+ input.excludeDerivedSummaries && entry.source === 'compaction_shed:summary'
331
+ if (derived || excludesSuccessfulTool(entry, input.excludeSuccessfulTools)) {
332
+ if (derived) excludedSummaries++
333
+ else excludedToolResults++
334
+ entryIndex++
335
+ chunk = 0
336
+ within = 0
337
+ continue
338
+ }
339
+ if (entry.truncated && !entry.spill) partial = true
340
+ if (
341
+ !entry.spill &&
342
+ !(selectedTerms ?? [query]).some((term) =>
343
+ input.matchMode === 'token'
344
+ ? mayContainToken(entry.tokenFilter, term) &&
345
+ (!input.caseSensitive || mayContain(entry.filter, term))
346
+ : !input.caseSensitive || mayContain(entry.filter, term),
347
+ )
348
+ ) {
349
+ entryIndex++
350
+ chunk = 0
351
+ within = 0
352
+ continue
353
+ }
354
+ const source = await readSource(entry)
355
+ while (chunk < source.chunks && matches.length < input.limit) {
356
+ signal?.throwIfAborted()
357
+ if (
358
+ (selectedTerms ?? [query]).some((term) =>
359
+ source.mayMatch(chunk, term, input.matchMode, input.caseSensitive),
360
+ )
361
+ ) {
362
+ const window = await source.window(chunk, input.matchMode === 'token')
363
+ const text = decode(window.bytes)
364
+ const page = passagesInWindow(
365
+ text,
366
+ Math.max(within, window.searchFrom ?? 0),
367
+ matchPassage,
368
+ input.limit - matches.length,
369
+ entry.spill ? (chunk + 1) * EVIDENCE_CHUNK_BYTES - window.offset : undefined,
370
+ )
371
+ within = page.next
372
+ for (const { start, end } of page.passages) {
373
+ const excerpt = text.slice(start, end)
374
+ const byteOffset = window.offset + Buffer.byteLength(text.slice(0, start))
375
+ matches.push({
376
+ address: seal.pack({ kind: 'text', entry: pointerSchema.parse(entry) }),
377
+ seq: entry.seq,
378
+ recordedAt: source.recordedAt,
379
+ source: entry.source,
380
+ part: entry.part,
381
+ characterOffset:
382
+ window.characterOffset === undefined
383
+ ? undefined
384
+ : window.characterOffset + start,
385
+ toolName: entry.toolName,
386
+ isError: entry.isError,
387
+ retained: source.retained,
388
+ excerpt,
389
+ excerptComplete:
390
+ source.retained === 'full' &&
391
+ byteOffset === 0 &&
392
+ Buffer.byteLength(excerpt) === source.bytes,
393
+ byteOffset,
394
+ })
395
+ }
396
+ if (within < text.length) break
397
+ }
398
+ within = 0
399
+ chunk++
400
+ if (browse) {
401
+ chunk = source.chunks
402
+ break
403
+ }
404
+ }
405
+ if (chunk < source.chunks) break
406
+ } catch (error) {
407
+ signal?.throwIfAborted()
408
+ if (error instanceof EvidencePageLimit) break
409
+ unavailable.push(`Text record ${entry.seq}/${entry.part} is unavailable or changed.`)
410
+ }
411
+ entryIndex++
412
+ chunk = 0
413
+ within = 0
414
+ }
415
+ const nextCursor =
416
+ entryIndex < page.entries.length
417
+ ? seal.pack({ ...cursor, entry: entryIndex, chunk, within })
418
+ : page.next && (input.seq === undefined || page.next.seq < input.seq)
419
+ ? seal.pack({ ...cursor, position: page.next, entry: 0, chunk: 0, within: 0 })
420
+ : null
421
+ return {
422
+ scope,
423
+ matches,
424
+ nextCursor,
425
+ scannedBytes: budget.bytes,
426
+ indexedRecords: cacheHit ? 0 : page.records,
427
+ cacheHit,
428
+ incomplete: nonterminal || unavailable.length > 0 || partial,
429
+ unavailable,
430
+ ...(excludedToolResults ? { excludedToolResults } : {}),
431
+ ...(excludedSummaries ? { excludedSummaries } : {}),
432
+ }
433
+ },
434
+ )
435
+ },
436
+ async read(
437
+ options: RunEvidenceReadOptions,
438
+ signal?: AbortSignal,
439
+ ): Promise<RunTextEvidenceReadResult> {
440
+ const input = z
441
+ .object({
442
+ address: z.string().max(8192),
443
+ byteOffset: integer.optional(),
444
+ maxReadBytes: integer
445
+ .min(1024 * 1024)
446
+ .max(PAGE_BYTES)
447
+ .optional(),
448
+ })
449
+ .strict()
450
+ .parse(options)
451
+ return access(signal, input.maxReadBytes, async (handle, _size, seal, _sourceKey, budget) => {
452
+ const pointer = addressSchema.parse(seal.unpack(input.address)).entry
453
+ const source = await createTextSourceReader(handle, runDir, scope.runId, budget)(pointer)
454
+ const entry = source.entry
455
+ if (mode === 'tools' && entry.source !== 'tool_completed')
456
+ throw new Error('Not tool evidence.')
457
+ return readTextPage(source, scope, input.byteOffset ?? 0, budget)
458
+ })
459
+ },
460
+ })
461
+ }
@@ -0,0 +1,126 @@
1
+ import { createHash } from 'node:crypto'
2
+ import { evidenceTokenEntries, evidenceTokenKey } from '../../utils/evidence-tokens.js'
3
+ import { RECORD_BYTES } from './io.js'
4
+
5
+ export const EVIDENCE_CHUNK_BYTES = 65_536
6
+ export const SEARCH_OVERLAP_BYTES = 1_024
7
+ const FILTER_BYTES = 1_024
8
+ const TOKEN_FILTER_PREFIX = `tokens-v1:${digest(`${process.version}:${process.versions.v8}:${process.versions.unicode}`).slice(0, 16)}:`
9
+
10
+ export function digest(value: string | Uint8Array): string {
11
+ return createHash('sha256').update(value).digest('hex')
12
+ }
13
+
14
+ function hashAt(text: string, offset: number): number {
15
+ let hash = 2166136261
16
+ for (let i = 0; i < 3; i++) hash = Math.imul(hash ^ text.charCodeAt(offset + i), 16777619)
17
+ return hash >>> 0
18
+ }
19
+ function second(hash: number): number {
20
+ return Math.imul(hash ^ (hash >>> 16), 0x45d9f3b) >>> 0
21
+ }
22
+ function contains(bits: Buffer, hash: number): boolean {
23
+ const bit = hash % (bits.length * 8)
24
+ return ((bits[bit >>> 3] ?? 0) & (1 << (bit & 7))) !== 0
25
+ }
26
+ function set(bits: Buffer, hash: number): void {
27
+ const bit = hash % (bits.length * 8)
28
+ bits[bit >>> 3] = (bits[bit >>> 3] ?? 0) | (1 << (bit & 7))
29
+ }
30
+
31
+ // A negative rules out a literal match; a positive always needs source verification.
32
+ export function textFilter(text: string): string {
33
+ const bits = Buffer.alloc(FILTER_BYTES)
34
+ for (let i = 0; i + 2 < text.length; i++) {
35
+ const hash = hashAt(text, i)
36
+ set(bits, hash)
37
+ set(bits, second(hash))
38
+ }
39
+ return bits.toString('base64')
40
+ }
41
+
42
+ export function mayContain(filter: string, query: string): boolean {
43
+ const bits = Buffer.from(filter, 'base64')
44
+ if (bits.length !== FILTER_BYTES) throw new Error('Invalid evidence filter.')
45
+ for (let i = 0; i + 2 < query.length; i++) {
46
+ const hash = hashAt(query, i)
47
+ if (!contains(bits, hash) || !contains(bits, second(hash))) return false
48
+ }
49
+ return true
50
+ }
51
+
52
+ function tokenHash(token: string): number {
53
+ let hash = 2166136261
54
+ for (let i = 0; i < token.length; i++) hash = Math.imul(hash ^ token.charCodeAt(i), 16777619)
55
+ return hash >>> 0
56
+ }
57
+
58
+ /** Negative-only membership filter using the same whole-token keys as discovery. */
59
+ export function tokenFilter(text: string): string {
60
+ const bits = Buffer.alloc(text.length <= 1024 ? 128 : text.length <= 8192 ? 512 : FILTER_BYTES)
61
+ for (const match of evidenceTokenEntries(text)) {
62
+ const hash = tokenHash(evidenceTokenKey(match[0]))
63
+ set(bits, hash)
64
+ set(bits, second(hash))
65
+ }
66
+ return TOKEN_FILTER_PREFIX + bits.toString('base64')
67
+ }
68
+
69
+ export function mayContainToken(filter: string | undefined, query: string): boolean {
70
+ if (filter === undefined || !filter.startsWith(TOKEN_FILTER_PREFIX)) return true
71
+ const bits = Buffer.from(filter.slice(TOKEN_FILTER_PREFIX.length), 'base64')
72
+ if (![128, 512, FILTER_BYTES].includes(bits.length))
73
+ throw new Error('Invalid evidence token filter.')
74
+ const hash = tokenHash(evidenceTokenKey(query))
75
+ return contains(bits, hash) && contains(bits, second(hash))
76
+ }
77
+
78
+ /** Internal manifest, authenticated by the digest recorded in tool_completed. */
79
+ export interface SpillManifest {
80
+ version: 1
81
+ bytes: number
82
+ chars?: number
83
+ chunkBytes: number
84
+ chunks: { sha256: string; filter: string; tokenFilter?: string; characterOffset?: number }[]
85
+ }
86
+
87
+ /** Optional acceleration must not reduce the previously retainable output size. */
88
+ export function encodeSpillManifest(manifest: SpillManifest): string {
89
+ const encoded = JSON.stringify(manifest)
90
+ if (Buffer.byteLength(encoded, 'utf8') <= RECORD_BYTES) return encoded
91
+ return JSON.stringify({
92
+ ...manifest,
93
+ chunks: manifest.chunks.map(({ tokenFilter: _filter, ...chunk }) => chunk),
94
+ })
95
+ }
96
+
97
+ export function spillManifest(bytes: Buffer): string {
98
+ const chunks: SpillManifest['chunks'] = []
99
+ let chars = 0
100
+ const boundary = (position: number) => {
101
+ let offset = position
102
+ while (offset < bytes.length && ((bytes[offset] ?? 0) & 0xc0) === 0x80) offset++
103
+ return Math.min(offset, bytes.length)
104
+ }
105
+ for (let offset = 0; offset < bytes.length; offset += EVIDENCE_CHUNK_BYTES) {
106
+ const text = bytes
107
+ .subarray(offset, offset + EVIDENCE_CHUNK_BYTES + SEARCH_OVERLAP_BYTES)
108
+ .toString('utf8')
109
+ chunks.push({
110
+ characterOffset: chars,
111
+ sha256: digest(bytes.subarray(offset, offset + EVIDENCE_CHUNK_BYTES)),
112
+ filter: textFilter(text),
113
+ tokenFilter: tokenFilter(text),
114
+ })
115
+ chars += bytes
116
+ .subarray(boundary(offset), boundary(offset + EVIDENCE_CHUNK_BYTES))
117
+ .toString('utf8').length
118
+ }
119
+ return encodeSpillManifest({
120
+ version: 1,
121
+ bytes: bytes.length,
122
+ chars,
123
+ chunkBytes: EVIDENCE_CHUNK_BYTES,
124
+ chunks,
125
+ })
126
+ }