@reticlehq/server 2.0.1 → 2.2.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 (479) hide show
  1. package/LICENSE-ENTERPRISE +37 -0
  2. package/README.md +5 -1
  3. package/dist/bridge-security.d.ts +1 -1
  4. package/dist/bridge-security.js +1 -1
  5. package/dist/bridge.d.ts +7 -0
  6. package/dist/bridge.d.ts.map +1 -1
  7. package/dist/bridge.js +62 -6
  8. package/dist/bridge.js.map +1 -1
  9. package/dist/bridge.test-harness.d.ts +5 -0
  10. package/dist/bridge.test-harness.d.ts.map +1 -1
  11. package/dist/bridge.test-harness.js +4 -0
  12. package/dist/bridge.test-harness.js.map +1 -1
  13. package/dist/capsule/capsule-store.d.ts +66 -0
  14. package/dist/capsule/capsule-store.d.ts.map +1 -0
  15. package/dist/capsule/capsule-store.js +110 -0
  16. package/dist/capsule/capsule-store.js.map +1 -0
  17. package/dist/capsule/capsule.d.ts +19 -0
  18. package/dist/capsule/capsule.d.ts.map +1 -0
  19. package/dist/capsule/capsule.js +36 -0
  20. package/dist/capsule/capsule.js.map +1 -0
  21. package/dist/capsule/causal-summary.d.ts +36 -0
  22. package/dist/capsule/causal-summary.d.ts.map +1 -0
  23. package/dist/capsule/causal-summary.js +111 -0
  24. package/dist/capsule/causal-summary.js.map +1 -0
  25. package/dist/capsule/divergence.d.ts +31 -0
  26. package/dist/capsule/divergence.d.ts.map +1 -0
  27. package/dist/capsule/divergence.js +41 -0
  28. package/dist/capsule/divergence.js.map +1 -0
  29. package/dist/capsule/minimize.d.ts +13 -0
  30. package/dist/capsule/minimize.d.ts.map +1 -0
  31. package/dist/capsule/minimize.js +23 -0
  32. package/dist/capsule/minimize.js.map +1 -0
  33. package/dist/capsule/predicate-to-links.d.ts +9 -0
  34. package/dist/capsule/predicate-to-links.d.ts.map +1 -0
  35. package/dist/capsule/predicate-to-links.js +31 -0
  36. package/dist/capsule/predicate-to-links.js.map +1 -0
  37. package/dist/cli-flow-commands.d.ts +31 -0
  38. package/dist/cli-flow-commands.d.ts.map +1 -0
  39. package/dist/cli-flow-commands.js +207 -0
  40. package/dist/cli-flow-commands.js.map +1 -0
  41. package/dist/cli-launch.d.ts.map +1 -1
  42. package/dist/cli-launch.js +1 -2
  43. package/dist/cli-launch.js.map +1 -1
  44. package/dist/cli-parse.d.ts +18 -2
  45. package/dist/cli-parse.d.ts.map +1 -1
  46. package/dist/cli-parse.js +57 -0
  47. package/dist/cli-parse.js.map +1 -1
  48. package/dist/cli-port.d.ts +10 -4
  49. package/dist/cli-port.d.ts.map +1 -1
  50. package/dist/cli-port.js +32 -6
  51. package/dist/cli-port.js.map +1 -1
  52. package/dist/cli-verify.d.ts.map +1 -1
  53. package/dist/cli-verify.js +29 -10
  54. package/dist/cli-verify.js.map +1 -1
  55. package/dist/cli.d.ts.map +1 -1
  56. package/dist/cli.js +83 -13
  57. package/dist/cli.js.map +1 -1
  58. package/dist/crawl/crawl-tools.d.ts.map +1 -1
  59. package/dist/crawl/crawl-tools.js +12 -0
  60. package/dist/crawl/crawl-tools.js.map +1 -1
  61. package/dist/crawl/crawl.d.ts +23 -1
  62. package/dist/crawl/crawl.d.ts.map +1 -1
  63. package/dist/crawl/crawl.js +42 -12
  64. package/dist/crawl/crawl.js.map +1 -1
  65. package/dist/daemon-resilience.d.ts +5 -5
  66. package/dist/daemon-resilience.js +5 -5
  67. package/dist/daemon.d.ts +9 -3
  68. package/dist/daemon.d.ts.map +1 -1
  69. package/dist/daemon.js +41 -8
  70. package/dist/daemon.js.map +1 -1
  71. package/dist/domain/domain-tools.d.ts.map +1 -1
  72. package/dist/domain/domain-tools.js +11 -1
  73. package/dist/domain/domain-tools.js.map +1 -1
  74. package/dist/domain/flow-risk.d.ts +4 -4
  75. package/dist/domain/flow-risk.js +4 -4
  76. package/dist/ee/audit-log.d.ts +2 -2
  77. package/dist/ee/audit-log.js +2 -2
  78. package/dist/events/event-filters.d.ts +35 -1
  79. package/dist/events/event-filters.d.ts.map +1 -1
  80. package/dist/events/event-filters.js +93 -6
  81. package/dist/events/event-filters.js.map +1 -1
  82. package/dist/events/predicate-eval.d.ts +15 -0
  83. package/dist/events/predicate-eval.d.ts.map +1 -1
  84. package/dist/events/predicate-eval.js +130 -9
  85. package/dist/events/predicate-eval.js.map +1 -1
  86. package/dist/events/predicate.d.ts +22 -1
  87. package/dist/events/predicate.d.ts.map +1 -1
  88. package/dist/events/predicate.js +169 -15
  89. package/dist/events/predicate.js.map +1 -1
  90. package/dist/events/ring-buffer.d.ts +10 -8
  91. package/dist/events/ring-buffer.d.ts.map +1 -1
  92. package/dist/events/ring-buffer.js +84 -25
  93. package/dist/events/ring-buffer.js.map +1 -1
  94. package/dist/flows/affected.d.ts +25 -0
  95. package/dist/flows/affected.d.ts.map +1 -0
  96. package/dist/flows/affected.js +36 -0
  97. package/dist/flows/affected.js.map +1 -0
  98. package/dist/flows/annotate.d.ts +4 -4
  99. package/dist/flows/annotate.js +4 -4
  100. package/dist/flows/assertion-integrity.d.ts +24 -0
  101. package/dist/flows/assertion-integrity.d.ts.map +1 -0
  102. package/dist/flows/assertion-integrity.js +27 -0
  103. package/dist/flows/assertion-integrity.js.map +1 -0
  104. package/dist/flows/assertion-tiers-store.d.ts +80 -0
  105. package/dist/flows/assertion-tiers-store.d.ts.map +1 -0
  106. package/dist/flows/assertion-tiers-store.js +99 -0
  107. package/dist/flows/assertion-tiers-store.js.map +1 -0
  108. package/dist/flows/buddy-status.d.ts +25 -0
  109. package/dist/flows/buddy-status.d.ts.map +1 -0
  110. package/dist/flows/buddy-status.js +33 -0
  111. package/dist/flows/buddy-status.js.map +1 -0
  112. package/dist/flows/coverage.d.ts +28 -0
  113. package/dist/flows/coverage.d.ts.map +1 -0
  114. package/dist/flows/coverage.js +22 -0
  115. package/dist/flows/coverage.js.map +1 -0
  116. package/dist/flows/decision.d.ts.map +1 -1
  117. package/dist/flows/decision.js +18 -9
  118. package/dist/flows/decision.js.map +1 -1
  119. package/dist/flows/flake-store.d.ts +20 -0
  120. package/dist/flows/flake-store.d.ts.map +1 -0
  121. package/dist/flows/flake-store.js +59 -0
  122. package/dist/flows/flake-store.js.map +1 -0
  123. package/dist/flows/flake.d.ts +58 -0
  124. package/dist/flows/flake.d.ts.map +1 -0
  125. package/dist/flows/flake.js +36 -0
  126. package/dist/flows/flake.js.map +1 -0
  127. package/dist/flows/flow-classify.d.ts +8 -8
  128. package/dist/flows/flow-classify.d.ts.map +1 -1
  129. package/dist/flows/flow-classify.js +12 -20
  130. package/dist/flows/flow-classify.js.map +1 -1
  131. package/dist/flows/flow-replay-run.d.ts +6 -0
  132. package/dist/flows/flow-replay-run.d.ts.map +1 -1
  133. package/dist/flows/flow-replay-run.js +49 -0
  134. package/dist/flows/flow-replay-run.js.map +1 -1
  135. package/dist/flows/flow-replay.d.ts +9 -0
  136. package/dist/flows/flow-replay.d.ts.map +1 -1
  137. package/dist/flows/flow-replay.js +52 -18
  138. package/dist/flows/flow-replay.js.map +1 -1
  139. package/dist/flows/flow-report.d.ts +4 -4
  140. package/dist/flows/flow-report.d.ts.map +1 -1
  141. package/dist/flows/flow-report.js +2 -1
  142. package/dist/flows/flow-report.js.map +1 -1
  143. package/dist/flows/flow-sources.d.ts +20 -0
  144. package/dist/flows/flow-sources.d.ts.map +1 -0
  145. package/dist/flows/flow-sources.js +33 -0
  146. package/dist/flows/flow-sources.js.map +1 -0
  147. package/dist/flows/flow-tools.d.ts +13 -1
  148. package/dist/flows/flow-tools.d.ts.map +1 -1
  149. package/dist/flows/flow-tools.js +97 -152
  150. package/dist/flows/flow-tools.js.map +1 -1
  151. package/dist/flows/flows.d.ts +9 -4
  152. package/dist/flows/flows.d.ts.map +1 -1
  153. package/dist/flows/flows.js +39 -27
  154. package/dist/flows/flows.js.map +1 -1
  155. package/dist/flows/gate.d.ts +39 -0
  156. package/dist/flows/gate.d.ts.map +1 -0
  157. package/dist/flows/gate.js +34 -0
  158. package/dist/flows/gate.js.map +1 -0
  159. package/dist/flows/git-changed.d.ts +9 -0
  160. package/dist/flows/git-changed.d.ts.map +1 -0
  161. package/dist/flows/git-changed.js +25 -0
  162. package/dist/flows/git-changed.js.map +1 -0
  163. package/dist/flows/heal-run.d.ts +19 -0
  164. package/dist/flows/heal-run.d.ts.map +1 -0
  165. package/dist/flows/heal-run.js +137 -0
  166. package/dist/flows/heal-run.js.map +1 -0
  167. package/dist/flows/parallel-suite.d.ts +27 -0
  168. package/dist/flows/parallel-suite.d.ts.map +1 -0
  169. package/dist/flows/parallel-suite.js +51 -0
  170. package/dist/flows/parallel-suite.js.map +1 -0
  171. package/dist/flows/replay.d.ts +13 -0
  172. package/dist/flows/replay.d.ts.map +1 -1
  173. package/dist/flows/replay.js +56 -23
  174. package/dist/flows/replay.js.map +1 -1
  175. package/dist/flows/watch-batcher.d.ts +18 -0
  176. package/dist/flows/watch-batcher.d.ts.map +1 -0
  177. package/dist/flows/watch-batcher.js +20 -0
  178. package/dist/flows/watch-batcher.js.map +1 -0
  179. package/dist/honesty/blind-spots.d.ts +37 -0
  180. package/dist/honesty/blind-spots.d.ts.map +1 -0
  181. package/dist/honesty/blind-spots.js +57 -0
  182. package/dist/honesty/blind-spots.js.map +1 -0
  183. package/dist/honesty/honesty.d.ts +57 -0
  184. package/dist/honesty/honesty.d.ts.map +1 -0
  185. package/dist/honesty/honesty.js +63 -0
  186. package/dist/honesty/honesty.js.map +1 -0
  187. package/dist/http-server.d.ts +5 -9
  188. package/dist/http-server.d.ts.map +1 -1
  189. package/dist/http-server.js +5 -9
  190. package/dist/http-server.js.map +1 -1
  191. package/dist/idle-shutdown.d.ts +2 -2
  192. package/dist/idle-shutdown.js +2 -2
  193. package/dist/index.d.ts +3 -3
  194. package/dist/index.d.ts.map +1 -1
  195. package/dist/index.js +131 -73
  196. package/dist/index.js.map +1 -1
  197. package/dist/init/agent-rules.d.ts +38 -0
  198. package/dist/init/agent-rules.d.ts.map +1 -0
  199. package/dist/init/agent-rules.js +65 -0
  200. package/dist/init/agent-rules.js.map +1 -0
  201. package/dist/init/mcp.d.ts.map +1 -1
  202. package/dist/init/mcp.js +4 -3
  203. package/dist/init/mcp.js.map +1 -1
  204. package/dist/init/plan.d.ts +6 -0
  205. package/dist/init/plan.d.ts.map +1 -1
  206. package/dist/init/plan.js +79 -3
  207. package/dist/init/plan.js.map +1 -1
  208. package/dist/init/run.d.ts.map +1 -1
  209. package/dist/init/run.js +4 -0
  210. package/dist/init/run.js.map +1 -1
  211. package/dist/init/snippets.js +1 -1
  212. package/dist/init/vite-config.d.ts +1 -1
  213. package/dist/init/vite-config.js +2 -2
  214. package/dist/init/vite-config.js.map +1 -1
  215. package/dist/input/network-detail.d.ts +74 -0
  216. package/dist/input/network-detail.d.ts.map +1 -0
  217. package/dist/input/network-detail.js +160 -0
  218. package/dist/input/network-detail.js.map +1 -0
  219. package/dist/input/network-mock-tools.d.ts.map +1 -1
  220. package/dist/input/network-mock-tools.js +1 -6
  221. package/dist/input/network-mock-tools.js.map +1 -1
  222. package/dist/input/network-mock.d.ts +4 -4
  223. package/dist/input/real-input.d.ts +44 -11
  224. package/dist/input/real-input.d.ts.map +1 -1
  225. package/dist/input/real-input.js +57 -9
  226. package/dist/input/real-input.js.map +1 -1
  227. package/dist/input/viewport-tools.d.ts.map +1 -1
  228. package/dist/input/viewport-tools.js +1 -6
  229. package/dist/input/viewport-tools.js.map +1 -1
  230. package/dist/journal/ambient-store.d.ts +16 -0
  231. package/dist/journal/ambient-store.d.ts.map +1 -0
  232. package/dist/journal/ambient-store.js +46 -0
  233. package/dist/journal/ambient-store.js.map +1 -0
  234. package/dist/journal/ambient.d.ts +48 -0
  235. package/dist/journal/ambient.d.ts.map +1 -0
  236. package/dist/journal/ambient.js +48 -0
  237. package/dist/journal/ambient.js.map +1 -0
  238. package/dist/journal/attach-journal.d.ts +22 -0
  239. package/dist/journal/attach-journal.d.ts.map +1 -0
  240. package/dist/journal/attach-journal.js +20 -0
  241. package/dist/journal/attach-journal.js.map +1 -0
  242. package/dist/journal/deviation-report.d.ts +28 -0
  243. package/dist/journal/deviation-report.d.ts.map +1 -0
  244. package/dist/journal/deviation-report.js +54 -0
  245. package/dist/journal/deviation-report.js.map +1 -0
  246. package/dist/journal/deviation-service.d.ts +12 -0
  247. package/dist/journal/deviation-service.d.ts.map +1 -0
  248. package/dist/journal/deviation-service.js +32 -0
  249. package/dist/journal/deviation-service.js.map +1 -0
  250. package/dist/journal/envelope-store.d.ts +19 -0
  251. package/dist/journal/envelope-store.d.ts.map +1 -0
  252. package/dist/journal/envelope-store.js +62 -0
  253. package/dist/journal/envelope-store.js.map +1 -0
  254. package/dist/journal/envelope.d.ts +232 -0
  255. package/dist/journal/envelope.d.ts.map +1 -0
  256. package/dist/journal/envelope.js +94 -0
  257. package/dist/journal/envelope.js.map +1 -0
  258. package/dist/journal/journal-query.d.ts +20 -0
  259. package/dist/journal/journal-query.d.ts.map +1 -0
  260. package/dist/journal/journal-query.js +28 -0
  261. package/dist/journal/journal-query.js.map +1 -0
  262. package/dist/journal/journal-recorder.d.ts +38 -0
  263. package/dist/journal/journal-recorder.d.ts.map +1 -0
  264. package/dist/journal/journal-recorder.js +81 -0
  265. package/dist/journal/journal-recorder.js.map +1 -0
  266. package/dist/journal/retention.d.ts +21 -0
  267. package/dist/journal/retention.d.ts.map +1 -0
  268. package/dist/journal/retention.js +50 -0
  269. package/dist/journal/retention.js.map +1 -0
  270. package/dist/journal/rollups.d.ts +49 -0
  271. package/dist/journal/rollups.d.ts.map +1 -0
  272. package/dist/journal/rollups.js +83 -0
  273. package/dist/journal/rollups.js.map +1 -0
  274. package/dist/journal/session-end.d.ts +32 -0
  275. package/dist/journal/session-end.d.ts.map +1 -0
  276. package/dist/journal/session-end.js +52 -0
  277. package/dist/journal/session-end.js.map +1 -0
  278. package/dist/journal/session-journal.d.ts +25 -0
  279. package/dist/journal/session-journal.d.ts.map +1 -0
  280. package/dist/journal/session-journal.js +168 -0
  281. package/dist/journal/session-journal.js.map +1 -0
  282. package/dist/license/license.d.ts +8 -3
  283. package/dist/license/license.d.ts.map +1 -1
  284. package/dist/license/license.js +34 -11
  285. package/dist/license/license.js.map +1 -1
  286. package/dist/mcp-proxy.d.ts +20 -0
  287. package/dist/mcp-proxy.d.ts.map +1 -1
  288. package/dist/mcp-proxy.js +52 -29
  289. package/dist/mcp-proxy.js.map +1 -1
  290. package/dist/mcp.d.ts +22 -0
  291. package/dist/mcp.d.ts.map +1 -1
  292. package/dist/mcp.js +93 -10
  293. package/dist/mcp.js.map +1 -1
  294. package/dist/oracles/flow-instrument-gaps.d.ts +19 -0
  295. package/dist/oracles/flow-instrument-gaps.d.ts.map +1 -0
  296. package/dist/oracles/flow-instrument-gaps.js +45 -0
  297. package/dist/oracles/flow-instrument-gaps.js.map +1 -0
  298. package/dist/oracles/propose-consequences.d.ts +22 -0
  299. package/dist/oracles/propose-consequences.d.ts.map +1 -0
  300. package/dist/oracles/propose-consequences.js +93 -0
  301. package/dist/oracles/propose-consequences.js.map +1 -0
  302. package/dist/oracles/self-instrument.d.ts +32 -0
  303. package/dist/oracles/self-instrument.d.ts.map +1 -0
  304. package/dist/oracles/self-instrument.js +44 -0
  305. package/dist/oracles/self-instrument.js.map +1 -0
  306. package/dist/pairing-token.d.ts +1 -1
  307. package/dist/phenomena/phenomena.d.ts +27 -0
  308. package/dist/phenomena/phenomena.d.ts.map +1 -0
  309. package/dist/phenomena/phenomena.js +102 -0
  310. package/dist/phenomena/phenomena.js.map +1 -0
  311. package/dist/pool/browser-pool.d.ts +5 -3
  312. package/dist/pool/browser-pool.d.ts.map +1 -1
  313. package/dist/pool/browser-pool.js +21 -3
  314. package/dist/pool/browser-pool.js.map +1 -1
  315. package/dist/pool/playwright-launcher.d.ts +2 -2
  316. package/dist/pool/playwright-launcher.d.ts.map +1 -1
  317. package/dist/pool/playwright-launcher.js +20 -6
  318. package/dist/pool/playwright-launcher.js.map +1 -1
  319. package/dist/project/file-lock.d.ts +2 -0
  320. package/dist/project/file-lock.d.ts.map +1 -0
  321. package/dist/project/file-lock.js +24 -0
  322. package/dist/project/file-lock.js.map +1 -0
  323. package/dist/project/fs-port.d.ts +18 -0
  324. package/dist/project/fs-port.d.ts.map +1 -1
  325. package/dist/project/fs-port.js +24 -2
  326. package/dist/project/fs-port.js.map +1 -1
  327. package/dist/project/project-store.d.ts.map +1 -1
  328. package/dist/project/project-store.js +13 -7
  329. package/dist/project/project-store.js.map +1 -1
  330. package/dist/project/project-tools.d.ts +0 -6
  331. package/dist/project/project-tools.d.ts.map +1 -1
  332. package/dist/project/project-tools.js +25 -7
  333. package/dist/project/project-tools.js.map +1 -1
  334. package/dist/project/reticle-dir.d.ts +39 -14
  335. package/dist/project/reticle-dir.d.ts.map +1 -1
  336. package/dist/project/reticle-dir.js +30 -4
  337. package/dist/project/reticle-dir.js.map +1 -1
  338. package/dist/runs/build-verification-run.d.ts +1 -1
  339. package/dist/runs/build-verification-run.js +1 -1
  340. package/dist/runs/repair-prompt.d.ts +2 -0
  341. package/dist/runs/repair-prompt.d.ts.map +1 -1
  342. package/dist/runs/repair-prompt.js +14 -1
  343. package/dist/runs/repair-prompt.js.map +1 -1
  344. package/dist/runs/reticle-runner.d.ts +1 -1
  345. package/dist/runs/reticle-runner.d.ts.map +1 -1
  346. package/dist/runs/run-diff.d.ts +34 -0
  347. package/dist/runs/run-diff.d.ts.map +1 -0
  348. package/dist/runs/run-diff.js +71 -0
  349. package/dist/runs/run-diff.js.map +1 -0
  350. package/dist/runs/run-store.d.ts +6 -1
  351. package/dist/runs/run-store.d.ts.map +1 -1
  352. package/dist/runs/run-store.js +22 -2
  353. package/dist/runs/run-store.js.map +1 -1
  354. package/dist/runs/run-tools.d.ts.map +1 -1
  355. package/dist/runs/run-tools.js +16 -3
  356. package/dist/runs/run-tools.js.map +1 -1
  357. package/dist/runs/verify-server.js +1 -1
  358. package/dist/runs/verify-server.js.map +1 -1
  359. package/dist/server-version.d.ts +5 -0
  360. package/dist/server-version.d.ts.map +1 -1
  361. package/dist/server-version.js +5 -0
  362. package/dist/server-version.js.map +1 -1
  363. package/dist/session/control-envelope.d.ts +9 -1
  364. package/dist/session/control-envelope.d.ts.map +1 -1
  365. package/dist/session/control-envelope.js +13 -1
  366. package/dist/session/control-envelope.js.map +1 -1
  367. package/dist/session/live-control-tools.d.ts +1 -1
  368. package/dist/session/live-control-tools.d.ts.map +1 -1
  369. package/dist/session/live-control-tools.js +2 -7
  370. package/dist/session/live-control-tools.js.map +1 -1
  371. package/dist/session/live-control.d.ts +38 -0
  372. package/dist/session/live-control.d.ts.map +1 -0
  373. package/dist/session/live-control.js +64 -0
  374. package/dist/session/live-control.js.map +1 -0
  375. package/dist/session/observed-state.d.ts +46 -0
  376. package/dist/session/observed-state.d.ts.map +1 -0
  377. package/dist/session/observed-state.js +76 -0
  378. package/dist/session/observed-state.js.map +1 -0
  379. package/dist/session/output-budget.d.ts +9 -0
  380. package/dist/session/output-budget.d.ts.map +1 -1
  381. package/dist/session/output-budget.js +12 -1
  382. package/dist/session/output-budget.js.map +1 -1
  383. package/dist/session/review-store.d.ts +1 -1
  384. package/dist/session/review-store.d.ts.map +1 -1
  385. package/dist/session/review-store.js +2 -2
  386. package/dist/session/review-store.js.map +1 -1
  387. package/dist/session/session-manager.d.ts +9 -7
  388. package/dist/session/session-manager.d.ts.map +1 -1
  389. package/dist/session/session-manager.js +8 -8
  390. package/dist/session/session-manager.js.map +1 -1
  391. package/dist/session/session-readiness.js +1 -1
  392. package/dist/session/session-readiness.js.map +1 -1
  393. package/dist/session/session-reaper.d.ts +1 -1
  394. package/dist/session/session-reaper.js +1 -1
  395. package/dist/session/session-recommendation.d.ts +1 -1
  396. package/dist/session/session-recommendation.js +1 -1
  397. package/dist/session/session-tools.js +1 -1
  398. package/dist/session/session-tools.js.map +1 -1
  399. package/dist/session/session.d.ts +44 -12
  400. package/dist/session/session.d.ts.map +1 -1
  401. package/dist/session/session.js +116 -47
  402. package/dist/session/session.js.map +1 -1
  403. package/dist/tools/act-tools.d.ts.map +1 -1
  404. package/dist/tools/act-tools.js +257 -70
  405. package/dist/tools/act-tools.js.map +1 -1
  406. package/dist/tools/act-view.d.ts +4 -4
  407. package/dist/tools/act-view.js +4 -4
  408. package/dist/tools/assert-grade.d.ts.map +1 -1
  409. package/dist/tools/assert-grade.js +15 -26
  410. package/dist/tools/assert-grade.js.map +1 -1
  411. package/dist/tools/browser-tools.d.ts.map +1 -1
  412. package/dist/tools/browser-tools.js +32 -8
  413. package/dist/tools/browser-tools.js.map +1 -1
  414. package/dist/tools/contract-tools.d.ts.map +1 -1
  415. package/dist/tools/contract-tools.js +5 -0
  416. package/dist/tools/contract-tools.js.map +1 -1
  417. package/dist/tools/dynamic-tools.d.ts.map +1 -1
  418. package/dist/tools/dynamic-tools.js +7 -6
  419. package/dist/tools/dynamic-tools.js.map +1 -1
  420. package/dist/tools/invoke-tool.d.ts.map +1 -1
  421. package/dist/tools/invoke-tool.js +41 -30
  422. package/dist/tools/invoke-tool.js.map +1 -1
  423. package/dist/tools/lease-tools.d.ts +16 -0
  424. package/dist/tools/lease-tools.d.ts.map +1 -1
  425. package/dist/tools/lease-tools.js +11 -0
  426. package/dist/tools/lease-tools.js.map +1 -1
  427. package/dist/tools/merge-tools.d.ts +43 -0
  428. package/dist/tools/merge-tools.d.ts.map +1 -0
  429. package/dist/tools/merge-tools.js +66 -0
  430. package/dist/tools/merge-tools.js.map +1 -0
  431. package/dist/tools/observe-tools.d.ts.map +1 -1
  432. package/dist/tools/observe-tools.js +172 -29
  433. package/dist/tools/observe-tools.js.map +1 -1
  434. package/dist/tools/profiles.d.ts +18 -13
  435. package/dist/tools/profiles.d.ts.map +1 -1
  436. package/dist/tools/profiles.js +39 -33
  437. package/dist/tools/profiles.js.map +1 -1
  438. package/dist/tools/query-paginate.d.ts +9 -2
  439. package/dist/tools/query-paginate.d.ts.map +1 -1
  440. package/dist/tools/query-paginate.js +21 -4
  441. package/dist/tools/query-paginate.js.map +1 -1
  442. package/dist/tools/read-tools.d.ts.map +1 -1
  443. package/dist/tools/read-tools.js +95 -2
  444. package/dist/tools/read-tools.js.map +1 -1
  445. package/dist/tools/snapshot-delta.d.ts +2 -0
  446. package/dist/tools/snapshot-delta.d.ts.map +1 -1
  447. package/dist/tools/snapshot-delta.js +0 -0
  448. package/dist/tools/snapshot-delta.js.map +1 -1
  449. package/dist/tools/tool-kit.d.ts +11 -2
  450. package/dist/tools/tool-kit.d.ts.map +1 -1
  451. package/dist/tools/tool-kit.js +24 -1
  452. package/dist/tools/tool-kit.js.map +1 -1
  453. package/dist/tools/tool-names.d.ts +19 -10
  454. package/dist/tools/tool-names.d.ts.map +1 -1
  455. package/dist/tools/tool-names.js +23 -13
  456. package/dist/tools/tool-names.js.map +1 -1
  457. package/dist/tools/tools-helpers.d.ts +12 -0
  458. package/dist/tools/tools-helpers.d.ts.map +1 -1
  459. package/dist/tools/tools-helpers.js +20 -0
  460. package/dist/tools/tools-helpers.js.map +1 -1
  461. package/dist/tools/tools.d.ts.map +1 -1
  462. package/dist/tools/tools.js +162 -12
  463. package/dist/tools/tools.js.map +1 -1
  464. package/dist/update/update-checker.d.ts +14 -1
  465. package/dist/update/update-checker.d.ts.map +1 -1
  466. package/dist/update/update-checker.js +9 -5
  467. package/dist/update/update-checker.js.map +1 -1
  468. package/dist/update/updater.d.ts +20 -2
  469. package/dist/update/updater.d.ts.map +1 -1
  470. package/dist/update/updater.js +48 -14
  471. package/dist/update/updater.js.map +1 -1
  472. package/dist/visual/visual-tools.d.ts.map +1 -1
  473. package/dist/visual/visual-tools.js +1 -6
  474. package/dist/visual/visual-tools.js.map +1 -1
  475. package/package.json +8 -3
  476. package/dist/update/update-tools.d.ts +0 -3
  477. package/dist/update/update-tools.d.ts.map +0 -1
  478. package/dist/update/update-tools.js +0 -94
  479. package/dist/update/update-tools.js.map +0 -1
@@ -0,0 +1,36 @@
1
+ /**
2
+ * The file→flow reverse index — the heart of the unavoidable loop. When a file changes, which flows must
3
+ * re-verify? A flow persists the source files its anchors were stamped from (its "sources manifest"); a
4
+ * changed file that appears in a flow's manifest makes that flow affected. A flow with NO manifest
5
+ * (recorded before v2.2, or un-stampable) is `unknown` — and unknown always means affected, never
6
+ * silently skipped: the loop fails safe toward re-verifying.
7
+ */
8
+ /** Normalize a path for comparison — strip a leading./ and any file:line suffix. */
9
+ function normalize(path) {
10
+ return path.replace(/^\.\//, '').replace(/:\d+(:\d+)?$/, '');
11
+ }
12
+ /**
13
+ * Which flows are affected by a set of changed files. Deterministic; a flow with no sources manifest is
14
+ * always affected (fail-safe). `changedFiles` and flow sources are matched by normalized path suffix so
15
+ * a repo-relative change matches an absolute stamp and vice-versa.
16
+ */
17
+ export function affectedFlows(flows, changedFiles) {
18
+ const changed = changedFiles.map(normalize);
19
+ const matchesChange = (source) => {
20
+ const s = normalize(source);
21
+ return changed.some((c) => c === s || c.endsWith(`/${s}`) || s.endsWith(`/${c}`));
22
+ };
23
+ const affected = [];
24
+ const unknownProvenance = [];
25
+ for (const flow of flows) {
26
+ if (flow.sources === undefined || flow.sources.length === 0) {
27
+ affected.push(flow.name);
28
+ unknownProvenance.push(flow.name);
29
+ continue;
30
+ }
31
+ if (flow.sources.some(matchesChange))
32
+ affected.push(flow.name);
33
+ }
34
+ return { affected, unknownProvenance };
35
+ }
36
+ //# sourceMappingURL=affected.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"affected.js","sourceRoot":"","sources":["../../src/flows/affected.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAeH,oFAAoF;AACpF,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,KAA6B,EAC7B,YAA+B;IAE/B,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC5C,MAAM,aAAa,GAAG,CAAC,MAAc,EAAW,EAAE;QAChD,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5B,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACpF,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,iBAAiB,GAAa,EAAE,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5D,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzB,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClC,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,CAAC;AACzC,CAAC"}
@@ -4,10 +4,10 @@ import { type Annotation, type AnnotateOutcome } from '@reticlehq/core';
4
4
  * the current captured-step count → an AnnotateOutcome (a result envelope + the patch to apply to
5
5
  * the AnnotationStore). No IO, no clock, unit-testable in isolation.
6
6
  *
7
- * assert-signal → step.expect.signal (+ signalData) on the LAST step (needs ≥1 step)
8
- * assert-visible → step.expect.element.testid on the LAST step (needs ≥1 step)
9
- * mark-dynamic → flow.dynamic[] += testid flow-level, allowed with 0 steps
10
- * success-state → flow.success = { signal | element } flow-level (signal XOR testid; both → signal)
7
+ * assert-signal → step.expect.signal (+ signalData) on the LAST step (needs ≥1 step)
8
+ * assert-visible → step.expect.element.testid on the LAST step (needs ≥1 step)
9
+ * mark-dynamic → flow.dynamic[] += testid flow-level, allowed with 0 steps
10
+ * success-state → flow.success = { signal | element } flow-level (signal XOR testid; both → signal)
11
11
  *
12
12
  * FIRST CUT: only the four structured kinds above. Free natural-language annotation → predicate
13
13
  * compilation is explicitly FUTURE — an NL string never reaches here (AnnotationSchema
@@ -4,10 +4,10 @@ import { AnnotationErrorCode, AnnotationKind, AnnotationTarget, COMPILED_PREDICA
4
4
  * the current captured-step count → an AnnotateOutcome (a result envelope + the patch to apply to
5
5
  * the AnnotationStore). No IO, no clock, unit-testable in isolation.
6
6
  *
7
- * assert-signal → step.expect.signal (+ signalData) on the LAST step (needs ≥1 step)
8
- * assert-visible → step.expect.element.testid on the LAST step (needs ≥1 step)
9
- * mark-dynamic → flow.dynamic[] += testid flow-level, allowed with 0 steps
10
- * success-state → flow.success = { signal | element } flow-level (signal XOR testid; both → signal)
7
+ * assert-signal → step.expect.signal (+ signalData) on the LAST step (needs ≥1 step)
8
+ * assert-visible → step.expect.element.testid on the LAST step (needs ≥1 step)
9
+ * mark-dynamic → flow.dynamic[] += testid flow-level, allowed with 0 steps
10
+ * success-state → flow.success = { signal | element } flow-level (signal XOR testid; both → signal)
11
11
  *
12
12
  * FIRST CUT: only the four structured kinds above. Free natural-language annotation → predicate
13
13
  * compilation is explicitly FUTURE — an NL string never reaches here (AnnotationSchema
@@ -0,0 +1,24 @@
1
+ import { type FlowExpect } from '@reticlehq/core';
2
+ /**
3
+ * Anti-reward-hacking (research-mandated). Test-gated agents pass gates by WEAKENING assertions — the
4
+ * canonical documented failure. Flows are git-checked and agent-editable, so a mustHold that dropped
5
+ * from a consequence (signal/net/state) to presence-only since the last passing run is a downgrade the
6
+ * gate must flag as a first-class finding, never silently accept. This is the pure detector; the gate
7
+ * and flow_verify surface it.
8
+ */
9
+ /** True when `after` weakened `before` — a real consequence became a fakeable presence-only check. */
10
+ export declare function isAssertionDowngrade(before: FlowExpect | undefined, after: FlowExpect | undefined): boolean;
11
+ export interface StepExpect {
12
+ step: number;
13
+ expect?: FlowExpect;
14
+ }
15
+ export interface DowngradeFinding {
16
+ step: number;
17
+ }
18
+ /**
19
+ * Compare a flow's steps between its last-passing version and now (matched by step index). Reports each
20
+ * step whose assertion tier dropped. Steps added/removed are out of scope here — deleted-flow detection
21
+ * lives with the affected index.
22
+ */
23
+ export declare function detectDowngrades(before: readonly StepExpect[], after: readonly StepExpect[]): DowngradeFinding[];
24
+ //# sourceMappingURL=assertion-integrity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertion-integrity.d.ts","sourceRoot":"","sources":["../../src/flows/assertion-integrity.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAC;AAEzB;;;;;;GAMG;AAEH,sGAAsG;AACtG,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,UAAU,GAAG,SAAS,EAC9B,KAAK,EAAE,UAAU,GAAG,SAAS,GAC5B,OAAO,CAET;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,UAAU,EAAE,EAC7B,KAAK,EAAE,SAAS,UAAU,EAAE,GAC3B,gBAAgB,EAAE,CAOpB"}
@@ -0,0 +1,27 @@
1
+ import { flowExpectHasConsequence, flowExpectIsPresenceOnly, } from '@reticlehq/core';
2
+ /**
3
+ * Anti-reward-hacking (research-mandated). Test-gated agents pass gates by WEAKENING assertions — the
4
+ * canonical documented failure. Flows are git-checked and agent-editable, so a mustHold that dropped
5
+ * from a consequence (signal/net/state) to presence-only since the last passing run is a downgrade the
6
+ * gate must flag as a first-class finding, never silently accept. This is the pure detector; the gate
7
+ * and flow_verify surface it.
8
+ */
9
+ /** True when `after` weakened `before` — a real consequence became a fakeable presence-only check. */
10
+ export function isAssertionDowngrade(before, after) {
11
+ return flowExpectHasConsequence(before) && flowExpectIsPresenceOnly(after);
12
+ }
13
+ /**
14
+ * Compare a flow's steps between its last-passing version and now (matched by step index). Reports each
15
+ * step whose assertion tier dropped. Steps added/removed are out of scope here — deleted-flow detection
16
+ * lives with the affected index.
17
+ */
18
+ export function detectDowngrades(before, after) {
19
+ const afterByStep = new Map(after.map((s) => [s.step, s.expect]));
20
+ const findings = [];
21
+ for (const { step, expect } of before) {
22
+ if (isAssertionDowngrade(expect, afterByStep.get(step)))
23
+ findings.push({ step });
24
+ }
25
+ return findings;
26
+ }
27
+ //# sourceMappingURL=assertion-integrity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertion-integrity.js","sourceRoot":"","sources":["../../src/flows/assertion-integrity.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,wBAAwB,GAEzB,MAAM,iBAAiB,CAAC;AAEzB;;;;;;GAMG;AAEH,sGAAsG;AACtG,MAAM,UAAU,oBAAoB,CAClC,MAA8B,EAC9B,KAA6B;IAE7B,OAAO,wBAAwB,CAAC,MAAM,CAAC,IAAI,wBAAwB,CAAC,KAAK,CAAC,CAAC;AAC7E,CAAC;AAWD;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAA6B,EAC7B,KAA4B;IAE5B,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAClE,MAAM,QAAQ,GAAuB,EAAE,CAAC;IACxC,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;QACtC,IAAI,oBAAoB,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IACnF,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,80 @@
1
+ import { z } from 'zod';
2
+ import type { FileSystemPort } from '../project/fs-port.js';
3
+ import type { StepExpect } from './assertion-integrity.js';
4
+ /**
5
+ * The anti-reward-hacking baseline. Detecting an assertion DOWNGRADE requires knowing what the
6
+ * flow asserted the last time it PASSED — otherwise a weakened flow simply looks like a flow that always
7
+ * asserted little. Flows are git-checked and agent-editable, so we cannot trust the file itself as its own
8
+ * history.
9
+ *
10
+ * So: on every passing replay we record that flow's per-step assertion shape here, and the gate diffs the
11
+ * current file against it. Recorded only on PASS, deliberately — a failing run must never become the
12
+ * baseline a later weakening is measured against.
13
+ *
14
+ * Loads never throw: a missing/corrupt ledger degrades to "no baseline", which means no downgrade can be
15
+ * claimed. Failing OPEN is right here — accusing an agent of gaming the gate on the strength of an
16
+ * unreadable file would be worse than missing one downgrade.
17
+ */
18
+ export declare const AssertionTiersFileSchema: z.ZodObject<{
19
+ version: z.ZodLiteral<1>;
20
+ flows: z.ZodRecord<z.ZodString, z.ZodObject<{
21
+ steps: z.ZodArray<z.ZodObject<{
22
+ step: z.ZodNumber;
23
+ expect: z.ZodOptional<z.ZodUnknown>;
24
+ }, "strip", z.ZodTypeAny, {
25
+ step: number;
26
+ expect?: unknown;
27
+ }, {
28
+ step: number;
29
+ expect?: unknown;
30
+ }>, "many">;
31
+ /** Source files this flow covered when it last passed — lets the gate scope DELETION findings to
32
+ * the files that actually changed, instead of flagging every intentionally-removed flow. */
33
+ sources: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
34
+ }, "strip", z.ZodTypeAny, {
35
+ steps: {
36
+ step: number;
37
+ expect?: unknown;
38
+ }[];
39
+ sources: string[];
40
+ }, {
41
+ steps: {
42
+ step: number;
43
+ expect?: unknown;
44
+ }[];
45
+ sources?: string[] | undefined;
46
+ }>>;
47
+ }, "strip", z.ZodTypeAny, {
48
+ version: 1;
49
+ flows: Record<string, {
50
+ steps: {
51
+ step: number;
52
+ expect?: unknown;
53
+ }[];
54
+ sources: string[];
55
+ }>;
56
+ }, {
57
+ version: 1;
58
+ flows: Record<string, {
59
+ steps: {
60
+ step: number;
61
+ expect?: unknown;
62
+ }[];
63
+ sources?: string[] | undefined;
64
+ }>;
65
+ }>;
66
+ export interface FlowBaseline {
67
+ steps: StepExpect[];
68
+ sources: string[];
69
+ }
70
+ export type FlowTiers = Record<string, FlowBaseline>;
71
+ export declare const ASSERTION_TIERS_VERSION = 1;
72
+ export declare class AssertionTiersStore {
73
+ #private;
74
+ constructor(fs: FileSystemPort, root: string);
75
+ load(): Promise<FlowTiers>;
76
+ save(tiers: FlowTiers): Promise<void>;
77
+ /** Record one flow's assertion shape + covered sources after it PASSED. Never breaks a replay. */
78
+ recordPassing(name: string, steps: readonly StepExpect[], sources?: readonly string[]): Promise<void>;
79
+ }
80
+ //# sourceMappingURL=assertion-tiers-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertion-tiers-store.d.ts","sourceRoot":"","sources":["../../src/flows/assertion-tiers-store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;QAK/B;oGAC4F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAIhG,CAAC;AAEH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AACD,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAErD,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC,qBAAa,mBAAmB;;gBAIlB,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM;IAKtC,IAAI,IAAI,OAAO,CAAC,SAAS,CAAC;IA6B1B,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ3C,kGAAkG;IAC5F,aAAa,CACjB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,OAAO,GAAE,SAAS,MAAM,EAAO,GAC9B,OAAO,CAAC,IAAI,CAAC;CAqBjB"}
@@ -0,0 +1,99 @@
1
+ import { dirname } from 'node:path';
2
+ import { z } from 'zod';
3
+ import { reticleDirPaths } from '../project/reticle-dir.js';
4
+ import { withFileLock } from '../project/file-lock.js';
5
+ /**
6
+ * The anti-reward-hacking baseline. Detecting an assertion DOWNGRADE requires knowing what the
7
+ * flow asserted the last time it PASSED — otherwise a weakened flow simply looks like a flow that always
8
+ * asserted little. Flows are git-checked and agent-editable, so we cannot trust the file itself as its own
9
+ * history.
10
+ *
11
+ * So: on every passing replay we record that flow's per-step assertion shape here, and the gate diffs the
12
+ * current file against it. Recorded only on PASS, deliberately — a failing run must never become the
13
+ * baseline a later weakening is measured against.
14
+ *
15
+ * Loads never throw: a missing/corrupt ledger degrades to "no baseline", which means no downgrade can be
16
+ * claimed. Failing OPEN is right here — accusing an agent of gaming the gate on the strength of an
17
+ * unreadable file would be worse than missing one downgrade.
18
+ */
19
+ export const AssertionTiersFileSchema = z.object({
20
+ version: z.literal(1),
21
+ flows: z.record(z.object({
22
+ steps: z.array(z.object({ step: z.number(), expect: z.unknown().optional() })),
23
+ /** Source files this flow covered when it last passed — lets the gate scope DELETION findings to
24
+ * the files that actually changed, instead of flagging every intentionally-removed flow. */
25
+ sources: z.array(z.string()).default([]),
26
+ })),
27
+ });
28
+ export const ASSERTION_TIERS_VERSION = 1;
29
+ export class AssertionTiersStore {
30
+ #fs;
31
+ #path;
32
+ constructor(fs, root) {
33
+ this.#fs = fs;
34
+ this.#path = reticleDirPaths(root).tiers;
35
+ }
36
+ async load() {
37
+ let text;
38
+ try {
39
+ text = await this.#fs.readFile(this.#path);
40
+ }
41
+ catch (error) {
42
+ if (this.#fs.isNotFound(error))
43
+ return {};
44
+ throw error;
45
+ }
46
+ let parsed;
47
+ try {
48
+ parsed = JSON.parse(text);
49
+ }
50
+ catch {
51
+ return {};
52
+ }
53
+ const result = AssertionTiersFileSchema.safeParse(parsed);
54
+ if (!result.success)
55
+ return {};
56
+ const out = {};
57
+ for (const [name, entry] of Object.entries(result.data.flows)) {
58
+ out[name] = {
59
+ steps: entry.steps.map((s) => ({
60
+ step: s.step,
61
+ ...(s.expect === undefined ? {} : { expect: s.expect }),
62
+ })),
63
+ sources: entry.sources,
64
+ };
65
+ }
66
+ return out;
67
+ }
68
+ async save(tiers) {
69
+ await this.#fs.mkdir(dirname(this.#path));
70
+ const body = `${JSON.stringify({ version: ASSERTION_TIERS_VERSION, flows: tiers }, null, 2)}\n`;
71
+ const tmp = `${this.#path}.tmp`;
72
+ await this.#fs.writeFile(tmp, body);
73
+ await this.#fs.rename(tmp, this.#path);
74
+ }
75
+ /** Record one flow's assertion shape + covered sources after it PASSED. Never breaks a replay. */
76
+ async recordPassing(name, steps, sources = []) {
77
+ try {
78
+ // Serialized per file: a fresh store instance is created per flow (flow-replay-run), so parallel
79
+ // passing replays would otherwise each load the same baseline, add only THEIR flow, and the last
80
+ // save would drop every other flow's baseline — the downgrade-detection gate silently losing
81
+ // coverage. The lock is keyed by path, so it serializes across those distinct instances.
82
+ await withFileLock(this.#path, async () => {
83
+ const all = await this.load();
84
+ all[name] = {
85
+ steps: steps.map((s) => ({
86
+ step: s.step,
87
+ ...(s.expect === undefined ? {} : { expect: s.expect }),
88
+ })),
89
+ sources: [...sources],
90
+ };
91
+ await this.save(all);
92
+ });
93
+ }
94
+ catch {
95
+ // a ledger write must never fail a green replay
96
+ }
97
+ }
98
+ }
99
+ //# sourceMappingURL=assertion-tiers-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertion-tiers-store.js","sourceRoot":"","sources":["../../src/flows/assertion-tiers-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The buddy channel. The co-dev experience for the HUMAN: a single ambient line they can park in
3
+ * a statusline or terminal and glance at — never a wall of output, never something they have to ask for.
4
+ *
5
+ * The rule this encodes: say the reassuring thing briefly and the alarming thing specifically. "41 flows
6
+ * nominal" needs no detail; a deviation needs its name, because a status line that says only "1 deviation"
7
+ * forces the human to go digging, which is exactly the work the buddy exists to remove.
8
+ */
9
+ export interface BuddyStatusInput {
10
+ /** Every saved flow. */
11
+ total: number;
12
+ /** Flows with a passing artifact. */
13
+ passing: number;
14
+ /** Flows that changed files put at risk and that have NO passing artifact — the actionable set. */
15
+ deviations: readonly string[];
16
+ /** Flows quarantined as flaky — surfaced, never blocking. */
17
+ quarantined: readonly string[];
18
+ }
19
+ /**
20
+ * One line, safe to print on every save. Shape:
21
+ * `✓ 41 flows nominal`
22
+ * `✗ 2 deviations: checkout, billing · 39 nominal · 1 flaky quarantined`
23
+ */
24
+ export declare function formatBuddyStatus(input: BuddyStatusInput): string;
25
+ //# sourceMappingURL=buddy-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buddy-status.d.ts","sourceRoot":"","sources":["../../src/flows/buddy-status.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,mGAAmG;IACnG,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,6DAA6D;IAC7D,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC;AAKD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAmBjE"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The buddy channel. The co-dev experience for the HUMAN: a single ambient line they can park in
3
+ * a statusline or terminal and glance at — never a wall of output, never something they have to ask for.
4
+ *
5
+ * The rule this encodes: say the reassuring thing briefly and the alarming thing specifically. "41 flows
6
+ * nominal" needs no detail; a deviation needs its name, because a status line that says only "1 deviation"
7
+ * forces the human to go digging, which is exactly the work the buddy exists to remove.
8
+ */
9
+ /** How many deviation names to spell out before collapsing to a count (a status line must stay one line). */
10
+ const MAX_NAMED = 2;
11
+ /**
12
+ * One line, safe to print on every save. Shape:
13
+ * `✓ 41 flows nominal`
14
+ * `✗ 2 deviations: checkout, billing · 39 nominal · 1 flaky quarantined`
15
+ */
16
+ export function formatBuddyStatus(input) {
17
+ const parts = [];
18
+ const deviations = input.deviations.length;
19
+ if (deviations === 0) {
20
+ parts.push(`✓ ${String(input.passing)}/${String(input.total)} flows nominal`);
21
+ }
22
+ else {
23
+ const named = input.deviations.slice(0, MAX_NAMED).join(', ');
24
+ const rest = deviations - Math.min(MAX_NAMED, deviations);
25
+ parts.push(`✗ ${String(deviations)} deviation${deviations === 1 ? '' : 's'}: ${named}${rest > 0 ? ` +${String(rest)} more` : ''}`);
26
+ parts.push(`${String(input.passing)} nominal`);
27
+ }
28
+ if (input.quarantined.length > 0) {
29
+ parts.push(`${String(input.quarantined.length)} flaky quarantined`);
30
+ }
31
+ return parts.join(' · ');
32
+ }
33
+ //# sourceMappingURL=buddy-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buddy-status.js","sourceRoot":"","sources":["../../src/flows/buddy-status.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH,6GAA6G;AAC7G,MAAM,SAAS,GAAG,CAAC,CAAC;AAEpB;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAuB;IACvD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;IAE3C,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAChF,CAAC;SAAM,CAAC;QACN,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9D,MAAM,IAAI,GAAG,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAC1D,KAAK,CAAC,IAAI,CACR,KAAK,MAAM,CAAC,UAAU,CAAC,aAAa,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CACvH,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACjD,CAAC;IAED,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Verified-surface coverage — the buddy channel's honest answer to "is EVERYTHING working?". A green on
3
+ * three flows says nothing about the twelve testids never exercised. This measures the declared surface
4
+ * (contract testids/signals/flows) actually touched by passing verification, so "everything" is honest
5
+ * about what everything means. Pure set math; the deviation report + gate carry the number.
6
+ */
7
+ export interface DeclaredSurface {
8
+ testids: readonly string[];
9
+ signals: readonly string[];
10
+ flows: readonly string[];
11
+ }
12
+ export interface CoverageDimension {
13
+ total: number;
14
+ covered: number;
15
+ /** Percent covered, rounded; 100 when nothing is declared (vacuously complete). */
16
+ pct: number;
17
+ /** Declared-but-never-exercised members — what "everything" is silently missing. */
18
+ uncovered: string[];
19
+ }
20
+ export interface Coverage {
21
+ testids: CoverageDimension;
22
+ signals: CoverageDimension;
23
+ flows: CoverageDimension;
24
+ /** Overall percent across all three dimensions combined. */
25
+ overallPct: number;
26
+ }
27
+ export declare function computeCoverage(declared: DeclaredSurface, exercised: DeclaredSurface): Coverage;
28
+ //# sourceMappingURL=coverage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../../src/flows/coverage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,mFAAmF;IACnF,GAAG,EAAE,MAAM,CAAC;IACZ,oFAAoF;IACpF,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,OAAO,EAAE,iBAAiB,CAAC;IAC3B,KAAK,EAAE,iBAAiB,CAAC;IACzB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;CACpB;AASD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,eAAe,EAAE,SAAS,EAAE,eAAe,GAAG,QAAQ,CAQ/F"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Verified-surface coverage — the buddy channel's honest answer to "is EVERYTHING working?". A green on
3
+ * three flows says nothing about the twelve testids never exercised. This measures the declared surface
4
+ * (contract testids/signals/flows) actually touched by passing verification, so "everything" is honest
5
+ * about what everything means. Pure set math; the deviation report + gate carry the number.
6
+ */
7
+ function dimension(declared, exercised) {
8
+ const uncovered = declared.filter((d) => !exercised.has(d));
9
+ const covered = declared.length - uncovered.length;
10
+ const pct = declared.length === 0 ? 100 : Math.round((covered / declared.length) * 100);
11
+ return { total: declared.length, covered, pct, uncovered };
12
+ }
13
+ export function computeCoverage(declared, exercised) {
14
+ const testids = dimension(declared.testids, new Set(exercised.testids));
15
+ const signals = dimension(declared.signals, new Set(exercised.signals));
16
+ const flows = dimension(declared.flows, new Set(exercised.flows));
17
+ const total = testids.total + signals.total + flows.total;
18
+ const covered = testids.covered + signals.covered + flows.covered;
19
+ const overallPct = total === 0 ? 100 : Math.round((covered / total) * 100);
20
+ return { testids, signals, flows, overallPct };
21
+ }
22
+ //# sourceMappingURL=coverage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage.js","sourceRoot":"","sources":["../../src/flows/coverage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAyBH,SAAS,SAAS,CAAC,QAA2B,EAAE,SAA8B;IAC5E,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;IACnD,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;IACxF,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,QAAyB,EAAE,SAA0B;IACnF,MAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IACxE,MAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IACxE,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IAClE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC1D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAClE,MAAM,UAAU,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;IAC3E,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AACjD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"decision.d.ts","sourceRoot":"","sources":["../../src/flows/decision.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,gBAAgB,EAErB,KAAK,cAAc,EAEnB,KAAK,YAAY,EAClB,MAAM,iBAAiB,CAAC;AA0BzB,wBAAgB,aAAa,CAAC,MAAM,EAAE,gBAAgB,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,cAAc,CAyDvF;AAQD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,aAAa,CAAC;IAAE,MAAM,EAAE,gBAAgB,CAAC;IAAC,IAAI,CAAC,EAAE,QAAQ,CAAA;CAAE,CAAC,GACjE,YAAY,CAuBd"}
1
+ {"version":3,"file":"decision.d.ts","sourceRoot":"","sources":["../../src/flows/decision.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,gBAAgB,EAErB,KAAK,cAAc,EAEnB,KAAK,YAAY,EAClB,MAAM,iBAAiB,CAAC;AAoCzB,wBAAgB,aAAa,CAAC,MAAM,EAAE,gBAAgB,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,cAAc,CAyDvF;AAQD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,aAAa,CAAC;IAAE,MAAM,EAAE,gBAAgB,CAAC;IAAC,IAAI,CAAC,EAAE,QAAQ,CAAA;CAAE,CAAC,GACjE,YAAY,CAuBd"}
@@ -1,24 +1,33 @@
1
1
  import { AnchorKind, ReplayStatus, } from '@reticlehq/core';
2
2
  import { classifyFlowAssertions } from './flow-classify.js';
3
+ import { SUCCESS_STEP_TOOL } from './flow-success.js';
3
4
  /**
4
5
  * Turn a replay result into the autonomy DECISION envelope — the judgement a human reviewer used to
5
6
  * make, expressed so a coding agent can act on it without one. Pure: no IO, no clock.
6
7
  *
7
- * pass → intent held; next action is none (or "add a consequence oracle" if the flow asserts nothing).
8
- * drift → a locator/anchor missed; point at WHERE (file:line from the source anchor) + a rebind hint.
9
- * fail → an action ran but its consequence/success oracle didn't fire (green-but-wrong) — check the handler.
8
+ * pass → intent held; next action is none (or "add a consequence oracle" if the flow asserts nothing).
9
+ * drift → a locator/anchor missed; point at WHERE (file:line from the source anchor) + a rebind hint.
10
+ * fail → an action ran but its consequence/success oracle didn't fire (green-but-wrong) — check the handler.
10
11
  */
11
12
  /** The first step that drifted or failed (drift takes precedence as the legible cause). */
12
13
  function failingStep(steps) {
13
14
  return steps.find((s) => s.drift !== undefined) ?? steps.find((s) => !s.ok);
14
15
  }
15
- /** `file:line` for a step, preferring the recorded component anchor's source, else the live page. */
16
+ /**
17
+ * `file:line` for a step, from whichever anchor recorded provenance — or nothing.
18
+ *
19
+ * It used to fall back to `step.page`, which meant a field named "whereInSource" could return
20
+ * "/checkout". The report writer renders it as **Where:** `<value>`, so a route arrived looking
21
+ * exactly like a file path. A locator that is sometimes a route cannot be trusted when it genuinely
22
+ * is a path, which costs more than the fallback ever added — the page is already reported separately
23
+ * on the step.
24
+ */
16
25
  function whereInSource(step, flow) {
17
26
  const anchor = flow?.steps[step.step]?.anchor;
18
- if (anchor?.kind === AnchorKind.COMPONENT && anchor.source !== undefined) {
19
- return `${anchor.source.file}:${anchor.source.line}`;
20
- }
21
- return step.page;
27
+ const source = anchor?.kind === AnchorKind.COMPONENT || anchor?.kind === AnchorKind.TESTID
28
+ ? anchor.source
29
+ : undefined;
30
+ return source === undefined ? undefined : `${source.file}:${String(source.line)}`;
22
31
  }
23
32
  export function buildDecision(result, flow) {
24
33
  const { name, status, steps } = result;
@@ -60,7 +69,7 @@ export function buildDecision(result, flow) {
60
69
  }
61
70
  // status error: an action failed, or the success oracle was not satisfied (green-but-wrong).
62
71
  const message = result.error?.message ?? step?.error ?? 'the flow failed';
63
- const isSuccessOracle = step?.tool === 'success';
72
+ const isSuccessOracle = step?.tool === SUCCESS_STEP_TOOL;
64
73
  return {
65
74
  verdict: 'fail',
66
75
  summary: `"${name}" failed${step !== undefined ? ` at step ${step.step} (${step.anchor})` : ''}.`,
@@ -1 +1 @@
1
- {"version":3,"file":"decision.js","sourceRoot":"","sources":["../../src/flows/decision.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"decision.js","sourceRoot":"","sources":["../../src/flows/decision.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { FileSystemPort } from '../project/fs-port.js';
2
+ import { type FlakeLedger } from './flake.js';
3
+ export declare const FLAKE_FILE_VERSION = 1;
4
+ /**
5
+ * Persists the per-flow flake ledger at `.reticle/flake.json`. Local single-project memory (stays OSS —
6
+ * OSS-VS-SERVER). Loads never throw: missing/malformed/wrong-version degrades to an empty ledger, so
7
+ * a bad file never blocks a gate — it just re-learns flakiness. `record` accrues one unchanged-code
8
+ * replay outcome; `flakyFlows` is what the gate quarantines.
9
+ */
10
+ export declare class FlakeStore {
11
+ #private;
12
+ constructor(fs: FileSystemPort, root: string);
13
+ load(): Promise<FlakeLedger>;
14
+ save(ledger: FlakeLedger): Promise<void>;
15
+ /** Accrue one unchanged-code replay outcome for a flow and persist. */
16
+ record(flow: string, passed: boolean): Promise<void>;
17
+ /** The flows currently quarantined as flaky — what the gate excludes from blocking. */
18
+ flakyFlows(): Promise<string[]>;
19
+ }
20
+ //# sourceMappingURL=flake-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flake-store.d.ts","sourceRoot":"","sources":["../../src/flows/flake-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAAwD,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAEpG,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC;;;;;GAKG;AACH,qBAAa,UAAU;;gBAIT,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM;IAKtC,IAAI,IAAI,OAAO,CAAC,WAAW,CAAC;IAkB5B,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ9C,uEAAuE;IACjE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAM1D,uFAAuF;IACjF,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAMtC"}
@@ -0,0 +1,59 @@
1
+ import { dirname } from 'node:path';
2
+ import { reticleDirPaths } from '../project/reticle-dir.js';
3
+ import { FlakeFileSchema, emptyRecord, isFlaky, recordOutcome } from './flake.js';
4
+ export const FLAKE_FILE_VERSION = 1;
5
+ /**
6
+ * Persists the per-flow flake ledger at `.reticle/flake.json`. Local single-project memory (stays OSS —
7
+ * OSS-VS-SERVER). Loads never throw: missing/malformed/wrong-version degrades to an empty ledger, so
8
+ * a bad file never blocks a gate — it just re-learns flakiness. `record` accrues one unchanged-code
9
+ * replay outcome; `flakyFlows` is what the gate quarantines.
10
+ */
11
+ export class FlakeStore {
12
+ #fs;
13
+ #path;
14
+ constructor(fs, root) {
15
+ this.#fs = fs;
16
+ this.#path = reticleDirPaths(root).flake;
17
+ }
18
+ async load() {
19
+ let text;
20
+ try {
21
+ text = await this.#fs.readFile(this.#path);
22
+ }
23
+ catch (error) {
24
+ if (this.#fs.isNotFound(error))
25
+ return {};
26
+ throw error;
27
+ }
28
+ let parsed;
29
+ try {
30
+ parsed = JSON.parse(text);
31
+ }
32
+ catch {
33
+ return {};
34
+ }
35
+ const result = FlakeFileSchema.safeParse(parsed);
36
+ return result.success ? result.data.flows : {};
37
+ }
38
+ async save(ledger) {
39
+ await this.#fs.mkdir(dirname(this.#path));
40
+ const body = `${JSON.stringify({ version: FLAKE_FILE_VERSION, flows: ledger }, null, 2)}\n`;
41
+ const tmp = `${this.#path}.tmp`;
42
+ await this.#fs.writeFile(tmp, body);
43
+ await this.#fs.rename(tmp, this.#path);
44
+ }
45
+ /** Accrue one unchanged-code replay outcome for a flow and persist. */
46
+ async record(flow, passed) {
47
+ const ledger = await this.load();
48
+ ledger[flow] = recordOutcome(ledger[flow] ?? emptyRecord(), passed);
49
+ await this.save(ledger);
50
+ }
51
+ /** The flows currently quarantined as flaky — what the gate excludes from blocking. */
52
+ async flakyFlows() {
53
+ const ledger = await this.load();
54
+ return Object.entries(ledger)
55
+ .filter(([, record]) => isFlaky(record))
56
+ .map(([flow]) => flow);
57
+ }
58
+ }
59
+ //# sourceMappingURL=flake-store.js.map