@reticlehq/server 2.2.1 → 2.4.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 (790) hide show
  1. package/README.md +1 -1
  2. package/dist/bridge-security.d.ts +0 -1
  3. package/dist/bridge-security.js +0 -1
  4. package/dist/bridge.d.ts +0 -1
  5. package/dist/bridge.js +102 -12
  6. package/dist/bridge.test-harness.d.ts +5 -1
  7. package/dist/bridge.test-harness.js +12 -1
  8. package/dist/capsule/capsule-store.d.ts +2 -3
  9. package/dist/capsule/capsule-store.js +0 -1
  10. package/dist/capsule/capsule.d.ts +0 -1
  11. package/dist/capsule/capsule.js +0 -1
  12. package/dist/capsule/causal-summary.d.ts +21 -1
  13. package/dist/capsule/causal-summary.js +20 -2
  14. package/dist/capsule/divergence.d.ts +0 -1
  15. package/dist/capsule/divergence.js +0 -1
  16. package/dist/capsule/minimize.d.ts +0 -1
  17. package/dist/capsule/minimize.js +0 -1
  18. package/dist/capsule/predicate-to-links.d.ts +0 -1
  19. package/dist/capsule/predicate-to-links.js +0 -1
  20. package/dist/cli-doctor.d.ts +6 -0
  21. package/dist/cli-doctor.js +60 -0
  22. package/dist/cli-flow-commands.d.ts +0 -1
  23. package/dist/cli-flow-commands.js +0 -1
  24. package/dist/cli-launch.d.ts +0 -1
  25. package/dist/cli-launch.js +7 -3
  26. package/dist/cli-parse.d.ts +47 -3
  27. package/dist/cli-parse.js +147 -13
  28. package/dist/cli-port.d.ts +3 -1
  29. package/dist/cli-port.js +21 -1
  30. package/dist/cli-verify.d.ts +0 -1
  31. package/dist/cli-verify.js +1 -2
  32. package/dist/cli.d.ts +0 -1
  33. package/dist/cli.js +88 -69
  34. package/dist/cloud/cloud-config.d.ts +0 -1
  35. package/dist/cloud/cloud-config.js +0 -1
  36. package/dist/cloud/cloud-sync.d.ts +4 -5
  37. package/dist/cloud/cloud-sync.js +0 -1
  38. package/dist/cloud-cli.d.ts +0 -1
  39. package/dist/cloud-cli.js +9 -2
  40. package/dist/crawl/crawl-tools.d.ts +0 -1
  41. package/dist/crawl/crawl-tools.js +1 -2
  42. package/dist/crawl/crawl.d.ts +17 -3
  43. package/dist/crawl/crawl.js +43 -4
  44. package/dist/daemon-resilience.d.ts +6 -1
  45. package/dist/daemon-resilience.js +63 -1
  46. package/dist/daemon.d.ts +23 -3
  47. package/dist/daemon.js +36 -24
  48. package/dist/domain/domain-model.d.ts +0 -1
  49. package/dist/domain/domain-model.js +1 -2
  50. package/dist/domain/domain-tools.d.ts +0 -7
  51. package/dist/domain/domain-tools.js +21 -4
  52. package/dist/domain/flow-risk.d.ts +0 -1
  53. package/dist/domain/flow-risk.js +0 -1
  54. package/dist/ee/audit-log.d.ts +0 -1
  55. package/dist/ee/audit-log.js +0 -1
  56. package/dist/events/body-failures.d.ts +4 -0
  57. package/dist/events/body-failures.js +113 -0
  58. package/dist/events/contradictions.d.ts +53 -0
  59. package/dist/events/contradictions.js +282 -0
  60. package/dist/events/echo-mismatch.d.ts +4 -0
  61. package/dist/events/echo-mismatch.js +138 -0
  62. package/dist/events/event-filters.d.ts +17 -3
  63. package/dist/events/event-filters.js +13 -3
  64. package/dist/events/json-salvage.d.ts +32 -0
  65. package/dist/events/json-salvage.js +96 -0
  66. package/dist/events/predicate-eval.d.ts +2 -1
  67. package/dist/events/predicate-eval.js +56 -9
  68. package/dist/events/predicate.d.ts +0 -1
  69. package/dist/events/predicate.js +56 -2
  70. package/dist/events/reaction.d.ts +0 -1
  71. package/dist/events/reaction.js +0 -1
  72. package/dist/events/reconcile.d.ts +39 -0
  73. package/dist/events/reconcile.js +211 -0
  74. package/dist/events/ring-buffer.d.ts +0 -1
  75. package/dist/events/ring-buffer.js +0 -1
  76. package/dist/events/stale-response.d.ts +4 -0
  77. package/dist/events/stale-response.js +139 -0
  78. package/dist/events/unit-mismatch.d.ts +16 -0
  79. package/dist/events/unit-mismatch.js +167 -0
  80. package/dist/flows/affected-tools.d.ts +18 -0
  81. package/dist/flows/affected-tools.js +52 -0
  82. package/dist/flows/affected.d.ts +0 -1
  83. package/dist/flows/affected.js +0 -1
  84. package/dist/flows/annotate-tools.d.ts +0 -1
  85. package/dist/flows/annotate-tools.js +21 -3
  86. package/dist/flows/annotate.d.ts +0 -1
  87. package/dist/flows/annotate.js +0 -1
  88. package/dist/flows/annotation-store.d.ts +0 -1
  89. package/dist/flows/annotation-store.js +0 -1
  90. package/dist/flows/assertion-integrity.d.ts +0 -1
  91. package/dist/flows/assertion-integrity.js +0 -1
  92. package/dist/flows/assertion-tiers-store.d.ts +0 -1
  93. package/dist/flows/assertion-tiers-store.js +0 -1
  94. package/dist/flows/buddy-status.d.ts +0 -1
  95. package/dist/flows/buddy-status.js +0 -1
  96. package/dist/flows/coverage.d.ts +0 -1
  97. package/dist/flows/coverage.js +0 -1
  98. package/dist/flows/decision.d.ts +0 -7
  99. package/dist/flows/decision.js +47 -7
  100. package/dist/flows/flake-store.d.ts +0 -1
  101. package/dist/flows/flake-store.js +0 -1
  102. package/dist/flows/flake.d.ts +0 -1
  103. package/dist/flows/flake.js +0 -1
  104. package/dist/flows/flow-classify.d.ts +0 -1
  105. package/dist/flows/flow-classify.js +0 -1
  106. package/dist/flows/flow-replay-run.d.ts +0 -1
  107. package/dist/flows/flow-replay-run.js +2 -3
  108. package/dist/flows/flow-replay.d.ts +20 -4
  109. package/dist/flows/flow-replay.js +9 -43
  110. package/dist/flows/flow-report.d.ts +0 -1
  111. package/dist/flows/flow-report.js +0 -1
  112. package/dist/flows/flow-scope.d.ts +0 -1
  113. package/dist/flows/flow-scope.js +0 -1
  114. package/dist/flows/flow-sources.d.ts +0 -1
  115. package/dist/flows/flow-sources.js +0 -1
  116. package/dist/flows/flow-step-runners.d.ts +23 -0
  117. package/dist/flows/flow-step-runners.js +102 -0
  118. package/dist/flows/flow-success.d.ts +0 -1
  119. package/dist/flows/flow-success.js +0 -1
  120. package/dist/flows/flow-tools.d.ts +0 -1
  121. package/dist/flows/flow-tools.js +44 -14
  122. package/dist/flows/flows.d.ts +6 -2
  123. package/dist/flows/flows.js +15 -2
  124. package/dist/flows/gate.d.ts +0 -1
  125. package/dist/flows/gate.js +0 -1
  126. package/dist/flows/git-changed.d.ts +0 -1
  127. package/dist/flows/git-changed.js +0 -1
  128. package/dist/flows/heal-run.d.ts +0 -1
  129. package/dist/flows/heal-run.js +0 -1
  130. package/dist/flows/heal.d.ts +0 -1
  131. package/dist/flows/heal.js +0 -1
  132. package/dist/flows/parallel-suite.d.ts +0 -1
  133. package/dist/flows/parallel-suite.js +0 -1
  134. package/dist/flows/recordings.d.ts +0 -1
  135. package/dist/flows/recordings.js +0 -1
  136. package/dist/flows/replay.d.ts +0 -1
  137. package/dist/flows/replay.js +71 -4
  138. package/dist/flows/server-verify.d.ts +0 -1
  139. package/dist/flows/server-verify.js +0 -1
  140. package/dist/flows/verify-change-tools.d.ts +2 -0
  141. package/dist/flows/verify-change-tools.js +187 -0
  142. package/dist/flows/watch-batcher.d.ts +0 -1
  143. package/dist/flows/watch-batcher.js +0 -1
  144. package/dist/honesty/accepted-write.d.ts +14 -0
  145. package/dist/honesty/accepted-write.js +17 -0
  146. package/dist/honesty/blind-spots.d.ts +18 -1
  147. package/dist/honesty/blind-spots.js +47 -5
  148. package/dist/honesty/honesty.d.ts +0 -1
  149. package/dist/honesty/honesty.js +0 -1
  150. package/dist/honesty/uncaptured-bodies.d.ts +19 -0
  151. package/dist/honesty/uncaptured-bodies.js +30 -0
  152. package/dist/honesty/unread-outcome.d.ts +2 -0
  153. package/dist/honesty/unread-outcome.js +50 -0
  154. package/dist/honesty/verified.d.ts +40 -0
  155. package/dist/honesty/verified.js +86 -0
  156. package/dist/http-server.d.ts +0 -1
  157. package/dist/http-server.js +5 -1
  158. package/dist/hunt/hunt-report.d.ts +50 -0
  159. package/dist/hunt/hunt-report.js +84 -0
  160. package/dist/idle-shutdown.d.ts +0 -1
  161. package/dist/idle-shutdown.js +0 -1
  162. package/dist/index.d.ts +0 -1
  163. package/dist/index.js +0 -1
  164. package/dist/init/agent-rules.d.ts +0 -1
  165. package/dist/init/agent-rules.js +4 -2
  166. package/dist/init/capabilities.d.ts +17 -0
  167. package/dist/init/capabilities.js +51 -0
  168. package/dist/init/cursor.d.ts +0 -1
  169. package/dist/init/cursor.js +0 -1
  170. package/dist/init/desktop-doctor.d.ts +40 -0
  171. package/dist/init/desktop-doctor.js +198 -0
  172. package/dist/init/detect.d.ts +25 -1
  173. package/dist/init/detect.js +65 -4
  174. package/dist/init/mcp.d.ts +0 -1
  175. package/dist/init/mcp.js +0 -1
  176. package/dist/init/next-patch.d.ts +41 -0
  177. package/dist/init/next-patch.js +106 -0
  178. package/dist/init/node-io.d.ts +0 -1
  179. package/dist/init/node-io.js +25 -1
  180. package/dist/init/patch-kind.d.ts +20 -0
  181. package/dist/init/patch-kind.js +10 -0
  182. package/dist/init/plan-framework.d.ts +35 -0
  183. package/dist/init/plan-framework.js +217 -0
  184. package/dist/init/plan.d.ts +55 -4
  185. package/dist/init/plan.js +130 -112
  186. package/dist/init/project-id.d.ts +0 -1
  187. package/dist/init/project-id.js +0 -1
  188. package/dist/init/run.d.ts +17 -1
  189. package/dist/init/run.js +237 -18
  190. package/dist/init/slash-command.d.ts +18 -0
  191. package/dist/init/slash-command.js +52 -0
  192. package/dist/init/snippets.d.ts +48 -3
  193. package/dist/init/snippets.js +156 -6
  194. package/dist/init/vite-config.d.ts +4 -11
  195. package/dist/init/vite-config.js +15 -8
  196. package/dist/input/driven-redaction.d.ts +15 -0
  197. package/dist/input/driven-redaction.js +76 -0
  198. package/dist/input/network-detail.d.ts +9 -4
  199. package/dist/input/network-detail.js +35 -16
  200. package/dist/input/network-mock-tools.d.ts +0 -1
  201. package/dist/input/network-mock-tools.js +3 -4
  202. package/dist/input/network-mock.d.ts +0 -1
  203. package/dist/input/network-mock.js +0 -1
  204. package/dist/input/real-input.d.ts +14 -1
  205. package/dist/input/real-input.js +45 -3
  206. package/dist/input/scroll-find.d.ts +0 -1
  207. package/dist/input/scroll-find.js +0 -1
  208. package/dist/input/scroll-tools.d.ts +0 -1
  209. package/dist/input/scroll-tools.js +0 -1
  210. package/dist/input/viewport-tools.d.ts +0 -1
  211. package/dist/input/viewport-tools.js +3 -4
  212. package/dist/journal/ambient-store.d.ts +0 -1
  213. package/dist/journal/ambient-store.js +0 -1
  214. package/dist/journal/ambient.d.ts +0 -1
  215. package/dist/journal/ambient.js +0 -1
  216. package/dist/journal/attach-journal.d.ts +0 -1
  217. package/dist/journal/attach-journal.js +0 -1
  218. package/dist/journal/deviation-report.d.ts +0 -1
  219. package/dist/journal/deviation-report.js +0 -1
  220. package/dist/journal/deviation-service.d.ts +0 -1
  221. package/dist/journal/deviation-service.js +0 -1
  222. package/dist/journal/envelope-store.d.ts +0 -1
  223. package/dist/journal/envelope-store.js +0 -1
  224. package/dist/journal/envelope.d.ts +8 -9
  225. package/dist/journal/envelope.js +0 -1
  226. package/dist/journal/journal-query.d.ts +0 -1
  227. package/dist/journal/journal-query.js +0 -1
  228. package/dist/journal/journal-recorder.d.ts +0 -1
  229. package/dist/journal/journal-recorder.js +0 -1
  230. package/dist/journal/retention.d.ts +0 -1
  231. package/dist/journal/retention.js +0 -1
  232. package/dist/journal/rollups.d.ts +0 -1
  233. package/dist/journal/rollups.js +0 -1
  234. package/dist/journal/session-end.d.ts +0 -1
  235. package/dist/journal/session-end.js +0 -1
  236. package/dist/journal/session-journal.d.ts +0 -1
  237. package/dist/journal/session-journal.js +0 -1
  238. package/dist/license/license.d.ts +0 -1
  239. package/dist/license/license.js +0 -1
  240. package/dist/log.d.ts +0 -1
  241. package/dist/log.js +0 -1
  242. package/dist/mcp-proxy.d.ts +35 -4
  243. package/dist/mcp-proxy.js +174 -28
  244. package/dist/mcp.d.ts +15 -1
  245. package/dist/mcp.js +145 -17
  246. package/dist/oracles/flow-instrument-gaps.d.ts +0 -1
  247. package/dist/oracles/flow-instrument-gaps.js +0 -1
  248. package/dist/oracles/propose-consequences.d.ts +0 -1
  249. package/dist/oracles/propose-consequences.js +0 -1
  250. package/dist/oracles/self-instrument.d.ts +0 -1
  251. package/dist/oracles/self-instrument.js +0 -1
  252. package/dist/pairing-token.d.ts +0 -1
  253. package/dist/pairing-token.js +0 -1
  254. package/dist/phenomena/phenomena.d.ts +0 -1
  255. package/dist/phenomena/phenomena.js +0 -1
  256. package/dist/pool/browser-pool.d.ts +0 -1
  257. package/dist/pool/browser-pool.js +0 -1
  258. package/dist/pool/lease-reaper.d.ts +0 -1
  259. package/dist/pool/lease-reaper.js +0 -1
  260. package/dist/pool/playwright-launcher.d.ts +0 -1
  261. package/dist/pool/playwright-launcher.js +10 -2
  262. package/dist/project/baselines.d.ts +0 -1
  263. package/dist/project/baselines.js +0 -1
  264. package/dist/project/file-lock.d.ts +2 -1
  265. package/dist/project/file-lock.js +12 -2
  266. package/dist/project/fs-port.d.ts +0 -1
  267. package/dist/project/fs-port.js +0 -1
  268. package/dist/project/project-store.d.ts +0 -1
  269. package/dist/project/project-store.js +0 -1
  270. package/dist/project/project-tools.d.ts +0 -1
  271. package/dist/project/project-tools.js +29 -4
  272. package/dist/project/reticle-dir.d.ts +0 -1
  273. package/dist/project/reticle-dir.js +0 -1
  274. package/dist/runs/build-verification-run.d.ts +0 -1
  275. package/dist/runs/build-verification-run.js +0 -1
  276. package/dist/runs/profile-redact.d.ts +0 -1
  277. package/dist/runs/profile-redact.js +0 -1
  278. package/dist/runs/render-report.d.ts +0 -1
  279. package/dist/runs/render-report.js +0 -1
  280. package/dist/runs/repair-prompt.d.ts +0 -1
  281. package/dist/runs/repair-prompt.js +0 -1
  282. package/dist/runs/replay-mapping.d.ts +0 -1
  283. package/dist/runs/replay-mapping.js +0 -1
  284. package/dist/runs/reticle-runner.d.ts +0 -1
  285. package/dist/runs/reticle-runner.js +4 -2
  286. package/dist/runs/risk-classify.d.ts +0 -1
  287. package/dist/runs/risk-classify.js +0 -1
  288. package/dist/runs/run-diff.d.ts +0 -1
  289. package/dist/runs/run-diff.js +0 -1
  290. package/dist/runs/run-store.d.ts +0 -1
  291. package/dist/runs/run-store.js +0 -1
  292. package/dist/runs/run-tools.d.ts +0 -1
  293. package/dist/runs/run-tools.js +0 -1
  294. package/dist/runs/runner-port.d.ts +0 -1
  295. package/dist/runs/runner-port.js +0 -1
  296. package/dist/runs/verification-sync.d.ts +0 -1
  297. package/dist/runs/verification-sync.js +0 -1
  298. package/dist/runs/verify-http.d.ts +0 -1
  299. package/dist/runs/verify-http.js +0 -1
  300. package/dist/runs/verify-server.d.ts +0 -1
  301. package/dist/runs/verify-server.js +0 -1
  302. package/dist/server-version.d.ts +0 -1
  303. package/dist/server-version.js +0 -1
  304. package/dist/session/command-timeout.d.ts +35 -0
  305. package/dist/session/command-timeout.js +41 -0
  306. package/dist/session/control-envelope.d.ts +2 -3
  307. package/dist/session/control-envelope.js +2 -3
  308. package/dist/session/last-act.d.ts +31 -0
  309. package/dist/session/last-act.js +24 -0
  310. package/dist/session/live-control-tools.d.ts +0 -1
  311. package/dist/session/live-control-tools.js +3 -4
  312. package/dist/session/live-control.d.ts +0 -1
  313. package/dist/session/live-control.js +0 -1
  314. package/dist/session/observed-state.d.ts +12 -2
  315. package/dist/session/observed-state.js +29 -2
  316. package/dist/session/output-budget.d.ts +0 -1
  317. package/dist/session/output-budget.js +0 -1
  318. package/dist/session/pending-commands.d.ts +12 -0
  319. package/dist/session/pending-commands.js +36 -0
  320. package/dist/session/presenter-args.d.ts +0 -1
  321. package/dist/session/presenter-args.js +0 -1
  322. package/dist/session/review-store.d.ts +0 -1
  323. package/dist/session/review-store.js +0 -1
  324. package/dist/session/session-health.d.ts +26 -2
  325. package/dist/session/session-health.js +13 -1
  326. package/dist/session/session-info.d.ts +29 -0
  327. package/dist/session/session-info.js +1 -0
  328. package/dist/session/session-lease.d.ts +25 -0
  329. package/dist/session/session-lease.js +14 -0
  330. package/dist/session/session-manager.d.ts +7 -19
  331. package/dist/session/session-manager.js +35 -2
  332. package/dist/session/session-readiness.d.ts +0 -1
  333. package/dist/session/session-readiness.js +3 -4
  334. package/dist/session/session-reaper.d.ts +0 -1
  335. package/dist/session/session-reaper.js +0 -1
  336. package/dist/session/session-recommendation.d.ts +0 -1
  337. package/dist/session/session-recommendation.js +0 -1
  338. package/dist/session/session-tools.d.ts +0 -1
  339. package/dist/session/session-tools.js +2 -3
  340. package/dist/session/session.d.ts +33 -53
  341. package/dist/session/session.js +102 -66
  342. package/dist/session/state-select.d.ts +0 -1
  343. package/dist/session/state-select.js +0 -1
  344. package/dist/telemetry/argument-shape.d.ts +41 -0
  345. package/dist/telemetry/argument-shape.js +87 -0
  346. package/dist/telemetry/bug-found.d.ts +33 -0
  347. package/dist/telemetry/bug-found.js +95 -0
  348. package/dist/telemetry/cli-telemetry.d.ts +13 -0
  349. package/dist/telemetry/cli-telemetry.js +43 -0
  350. package/dist/telemetry/connect-failure.d.ts +16 -0
  351. package/dist/telemetry/connect-failure.js +44 -0
  352. package/dist/telemetry/daemon-telemetry.d.ts +19 -0
  353. package/dist/telemetry/daemon-telemetry.js +76 -0
  354. package/dist/telemetry/dev-repo.d.ts +10 -0
  355. package/dist/telemetry/dev-repo.js +80 -0
  356. package/dist/telemetry/error-fingerprint.d.ts +24 -0
  357. package/dist/telemetry/error-fingerprint.js +88 -0
  358. package/dist/telemetry/feedback-cli.d.ts +31 -0
  359. package/dist/telemetry/feedback-cli.js +102 -0
  360. package/dist/telemetry/feedback-context.d.ts +32 -0
  361. package/dist/telemetry/feedback-context.js +143 -0
  362. package/dist/telemetry/feedback.d.ts +66 -0
  363. package/dist/telemetry/feedback.js +175 -0
  364. package/dist/telemetry/git-facts.d.ts +21 -0
  365. package/dist/telemetry/git-facts.js +109 -0
  366. package/dist/telemetry/identify.d.ts +22 -0
  367. package/dist/telemetry/identify.js +73 -0
  368. package/dist/telemetry/init-telemetry.d.ts +26 -0
  369. package/dist/telemetry/init-telemetry.js +33 -0
  370. package/dist/telemetry/machine-snapshot.d.ts +6 -0
  371. package/dist/telemetry/machine-snapshot.js +39 -0
  372. package/dist/telemetry/mcp-connection.d.ts +5 -0
  373. package/dist/telemetry/mcp-connection.js +44 -0
  374. package/dist/telemetry/project-profile.d.ts +44 -0
  375. package/dist/telemetry/project-profile.js +205 -0
  376. package/dist/telemetry/run-telemetry.d.ts +21 -0
  377. package/dist/telemetry/run-telemetry.js +62 -0
  378. package/dist/telemetry/session-metrics.d.ts +103 -0
  379. package/dist/telemetry/session-metrics.js +329 -0
  380. package/dist/telemetry/telemetry.d.ts +35 -8
  381. package/dist/telemetry/telemetry.js +105 -12
  382. package/dist/token-auth.d.ts +0 -1
  383. package/dist/token-auth.js +0 -1
  384. package/dist/tools/act-capsule.d.ts +23 -0
  385. package/dist/tools/act-capsule.js +47 -0
  386. package/dist/tools/act-danger.d.ts +7 -0
  387. package/dist/tools/act-danger.js +44 -0
  388. package/dist/tools/act-helpers.d.ts +17 -0
  389. package/dist/tools/act-helpers.js +40 -0
  390. package/dist/tools/act-tools.d.ts +8 -1
  391. package/dist/tools/act-tools.js +96 -98
  392. package/dist/tools/act-view.d.ts +7 -1
  393. package/dist/tools/act-view.js +13 -1
  394. package/dist/tools/assert-grade.d.ts +22 -1
  395. package/dist/tools/assert-grade.js +46 -1
  396. package/dist/tools/assert-verdict.d.ts +21 -0
  397. package/dist/tools/assert-verdict.js +62 -0
  398. package/dist/tools/browser-tools.d.ts +0 -1
  399. package/dist/tools/browser-tools.js +2 -2
  400. package/dist/tools/contract-tools.d.ts +0 -1
  401. package/dist/tools/contract-tools.js +0 -1
  402. package/dist/tools/coverage-tools.d.ts +9 -0
  403. package/dist/tools/coverage-tools.js +92 -0
  404. package/dist/tools/dynamic-tools.d.ts +0 -1
  405. package/dist/tools/dynamic-tools.js +21 -2
  406. package/dist/tools/error-recovery.d.ts +18 -2
  407. package/dist/tools/error-recovery.js +42 -7
  408. package/dist/tools/feedback-tools.d.ts +24 -0
  409. package/dist/tools/feedback-tools.js +180 -0
  410. package/dist/tools/invoke-tool.d.ts +0 -1
  411. package/dist/tools/invoke-tool.js +115 -5
  412. package/dist/tools/lease-tools.d.ts +0 -1
  413. package/dist/tools/lease-tools.js +6 -5
  414. package/dist/tools/merge-tools.d.ts +0 -1
  415. package/dist/tools/merge-tools.js +0 -1
  416. package/dist/tools/observe-tools.d.ts +0 -1
  417. package/dist/tools/observe-tools.js +91 -39
  418. package/dist/tools/profiles.d.ts +1 -2
  419. package/dist/tools/profiles.js +43 -16
  420. package/dist/tools/query-paginate.d.ts +0 -1
  421. package/dist/tools/query-paginate.js +0 -1
  422. package/dist/tools/read-tools.d.ts +0 -1
  423. package/dist/tools/read-tools.js +14 -8
  424. package/dist/tools/reconcile-tools.d.ts +2 -0
  425. package/dist/tools/reconcile-tools.js +111 -0
  426. package/dist/tools/snapshot-delta.d.ts +0 -1
  427. package/dist/tools/snapshot-delta.js +0 -0
  428. package/dist/tools/tool-invoker.d.ts +0 -1
  429. package/dist/tools/tool-invoker.js +0 -1
  430. package/dist/tools/tool-kit.d.ts +16 -1
  431. package/dist/tools/tool-kit.js +8 -2
  432. package/dist/tools/tool-names.d.ts +6 -1
  433. package/dist/tools/tool-names.js +6 -1
  434. package/dist/tools/tools-helpers.d.ts +0 -1
  435. package/dist/tools/tools-helpers.js +0 -1
  436. package/dist/tools/tools.d.ts +0 -1
  437. package/dist/tools/tools.js +24 -4
  438. package/dist/update/update-checker.d.ts +0 -1
  439. package/dist/update/update-checker.js +0 -1
  440. package/dist/update/update-nudge.d.ts +20 -0
  441. package/dist/update/update-nudge.js +72 -0
  442. package/dist/update/updater.d.ts +14 -1
  443. package/dist/update/updater.js +33 -2
  444. package/dist/visual/visual-diff.d.ts +0 -1
  445. package/dist/visual/visual-diff.js +0 -1
  446. package/dist/visual/visual-store.d.ts +0 -1
  447. package/dist/visual/visual-store.js +0 -1
  448. package/dist/visual/visual-tools.d.ts +0 -1
  449. package/dist/visual/visual-tools.js +103 -16
  450. package/package.json +2 -2
  451. package/dist/bridge-security.d.ts.map +0 -1
  452. package/dist/bridge-security.js.map +0 -1
  453. package/dist/bridge.d.ts.map +0 -1
  454. package/dist/bridge.js.map +0 -1
  455. package/dist/bridge.test-harness.d.ts.map +0 -1
  456. package/dist/bridge.test-harness.js.map +0 -1
  457. package/dist/capsule/capsule-store.d.ts.map +0 -1
  458. package/dist/capsule/capsule-store.js.map +0 -1
  459. package/dist/capsule/capsule.d.ts.map +0 -1
  460. package/dist/capsule/capsule.js.map +0 -1
  461. package/dist/capsule/causal-summary.d.ts.map +0 -1
  462. package/dist/capsule/causal-summary.js.map +0 -1
  463. package/dist/capsule/divergence.d.ts.map +0 -1
  464. package/dist/capsule/divergence.js.map +0 -1
  465. package/dist/capsule/minimize.d.ts.map +0 -1
  466. package/dist/capsule/minimize.js.map +0 -1
  467. package/dist/capsule/predicate-to-links.d.ts.map +0 -1
  468. package/dist/capsule/predicate-to-links.js.map +0 -1
  469. package/dist/cli-flow-commands.d.ts.map +0 -1
  470. package/dist/cli-flow-commands.js.map +0 -1
  471. package/dist/cli-launch.d.ts.map +0 -1
  472. package/dist/cli-launch.js.map +0 -1
  473. package/dist/cli-parse.d.ts.map +0 -1
  474. package/dist/cli-parse.js.map +0 -1
  475. package/dist/cli-port.d.ts.map +0 -1
  476. package/dist/cli-port.js.map +0 -1
  477. package/dist/cli-verify.d.ts.map +0 -1
  478. package/dist/cli-verify.js.map +0 -1
  479. package/dist/cli.d.ts.map +0 -1
  480. package/dist/cli.js.map +0 -1
  481. package/dist/cloud/cloud-config.d.ts.map +0 -1
  482. package/dist/cloud/cloud-config.js.map +0 -1
  483. package/dist/cloud/cloud-sync.d.ts.map +0 -1
  484. package/dist/cloud/cloud-sync.js.map +0 -1
  485. package/dist/cloud-cli.d.ts.map +0 -1
  486. package/dist/cloud-cli.js.map +0 -1
  487. package/dist/crawl/crawl-tools.d.ts.map +0 -1
  488. package/dist/crawl/crawl-tools.js.map +0 -1
  489. package/dist/crawl/crawl.d.ts.map +0 -1
  490. package/dist/crawl/crawl.js.map +0 -1
  491. package/dist/daemon-resilience.d.ts.map +0 -1
  492. package/dist/daemon-resilience.js.map +0 -1
  493. package/dist/daemon.d.ts.map +0 -1
  494. package/dist/daemon.js.map +0 -1
  495. package/dist/domain/domain-model.d.ts.map +0 -1
  496. package/dist/domain/domain-model.js.map +0 -1
  497. package/dist/domain/domain-tools.d.ts.map +0 -1
  498. package/dist/domain/domain-tools.js.map +0 -1
  499. package/dist/domain/flow-risk.d.ts.map +0 -1
  500. package/dist/domain/flow-risk.js.map +0 -1
  501. package/dist/ee/audit-log.d.ts.map +0 -1
  502. package/dist/ee/audit-log.js.map +0 -1
  503. package/dist/events/event-filters.d.ts.map +0 -1
  504. package/dist/events/event-filters.js.map +0 -1
  505. package/dist/events/predicate-eval.d.ts.map +0 -1
  506. package/dist/events/predicate-eval.js.map +0 -1
  507. package/dist/events/predicate.d.ts.map +0 -1
  508. package/dist/events/predicate.js.map +0 -1
  509. package/dist/events/reaction.d.ts.map +0 -1
  510. package/dist/events/reaction.js.map +0 -1
  511. package/dist/events/ring-buffer.d.ts.map +0 -1
  512. package/dist/events/ring-buffer.js.map +0 -1
  513. package/dist/flows/affected.d.ts.map +0 -1
  514. package/dist/flows/affected.js.map +0 -1
  515. package/dist/flows/annotate-tools.d.ts.map +0 -1
  516. package/dist/flows/annotate-tools.js.map +0 -1
  517. package/dist/flows/annotate.d.ts.map +0 -1
  518. package/dist/flows/annotate.js.map +0 -1
  519. package/dist/flows/annotation-store.d.ts.map +0 -1
  520. package/dist/flows/annotation-store.js.map +0 -1
  521. package/dist/flows/assertion-integrity.d.ts.map +0 -1
  522. package/dist/flows/assertion-integrity.js.map +0 -1
  523. package/dist/flows/assertion-tiers-store.d.ts.map +0 -1
  524. package/dist/flows/assertion-tiers-store.js.map +0 -1
  525. package/dist/flows/buddy-status.d.ts.map +0 -1
  526. package/dist/flows/buddy-status.js.map +0 -1
  527. package/dist/flows/coverage.d.ts.map +0 -1
  528. package/dist/flows/coverage.js.map +0 -1
  529. package/dist/flows/decision.d.ts.map +0 -1
  530. package/dist/flows/decision.js.map +0 -1
  531. package/dist/flows/flake-store.d.ts.map +0 -1
  532. package/dist/flows/flake-store.js.map +0 -1
  533. package/dist/flows/flake.d.ts.map +0 -1
  534. package/dist/flows/flake.js.map +0 -1
  535. package/dist/flows/flow-classify.d.ts.map +0 -1
  536. package/dist/flows/flow-classify.js.map +0 -1
  537. package/dist/flows/flow-replay-run.d.ts.map +0 -1
  538. package/dist/flows/flow-replay-run.js.map +0 -1
  539. package/dist/flows/flow-replay.d.ts.map +0 -1
  540. package/dist/flows/flow-replay.js.map +0 -1
  541. package/dist/flows/flow-report.d.ts.map +0 -1
  542. package/dist/flows/flow-report.js.map +0 -1
  543. package/dist/flows/flow-scope.d.ts.map +0 -1
  544. package/dist/flows/flow-scope.js.map +0 -1
  545. package/dist/flows/flow-sources.d.ts.map +0 -1
  546. package/dist/flows/flow-sources.js.map +0 -1
  547. package/dist/flows/flow-success.d.ts.map +0 -1
  548. package/dist/flows/flow-success.js.map +0 -1
  549. package/dist/flows/flow-tools.d.ts.map +0 -1
  550. package/dist/flows/flow-tools.js.map +0 -1
  551. package/dist/flows/flows.d.ts.map +0 -1
  552. package/dist/flows/flows.js.map +0 -1
  553. package/dist/flows/gate.d.ts.map +0 -1
  554. package/dist/flows/gate.js.map +0 -1
  555. package/dist/flows/git-changed.d.ts.map +0 -1
  556. package/dist/flows/git-changed.js.map +0 -1
  557. package/dist/flows/heal-run.d.ts.map +0 -1
  558. package/dist/flows/heal-run.js.map +0 -1
  559. package/dist/flows/heal.d.ts.map +0 -1
  560. package/dist/flows/heal.js.map +0 -1
  561. package/dist/flows/parallel-suite.d.ts.map +0 -1
  562. package/dist/flows/parallel-suite.js.map +0 -1
  563. package/dist/flows/recordings.d.ts.map +0 -1
  564. package/dist/flows/recordings.js.map +0 -1
  565. package/dist/flows/replay.d.ts.map +0 -1
  566. package/dist/flows/replay.js.map +0 -1
  567. package/dist/flows/server-verify.d.ts.map +0 -1
  568. package/dist/flows/server-verify.js.map +0 -1
  569. package/dist/flows/watch-batcher.d.ts.map +0 -1
  570. package/dist/flows/watch-batcher.js.map +0 -1
  571. package/dist/honesty/blind-spots.d.ts.map +0 -1
  572. package/dist/honesty/blind-spots.js.map +0 -1
  573. package/dist/honesty/honesty.d.ts.map +0 -1
  574. package/dist/honesty/honesty.js.map +0 -1
  575. package/dist/http-server.d.ts.map +0 -1
  576. package/dist/http-server.js.map +0 -1
  577. package/dist/idle-shutdown.d.ts.map +0 -1
  578. package/dist/idle-shutdown.js.map +0 -1
  579. package/dist/index.d.ts.map +0 -1
  580. package/dist/index.js.map +0 -1
  581. package/dist/init/agent-rules.d.ts.map +0 -1
  582. package/dist/init/agent-rules.js.map +0 -1
  583. package/dist/init/cursor.d.ts.map +0 -1
  584. package/dist/init/cursor.js.map +0 -1
  585. package/dist/init/detect.d.ts.map +0 -1
  586. package/dist/init/detect.js.map +0 -1
  587. package/dist/init/mcp.d.ts.map +0 -1
  588. package/dist/init/mcp.js.map +0 -1
  589. package/dist/init/node-io.d.ts.map +0 -1
  590. package/dist/init/node-io.js.map +0 -1
  591. package/dist/init/plan.d.ts.map +0 -1
  592. package/dist/init/plan.js.map +0 -1
  593. package/dist/init/project-id.d.ts.map +0 -1
  594. package/dist/init/project-id.js.map +0 -1
  595. package/dist/init/run.d.ts.map +0 -1
  596. package/dist/init/run.js.map +0 -1
  597. package/dist/init/snippets.d.ts.map +0 -1
  598. package/dist/init/snippets.js.map +0 -1
  599. package/dist/init/vite-config.d.ts.map +0 -1
  600. package/dist/init/vite-config.js.map +0 -1
  601. package/dist/input/network-detail.d.ts.map +0 -1
  602. package/dist/input/network-detail.js.map +0 -1
  603. package/dist/input/network-mock-tools.d.ts.map +0 -1
  604. package/dist/input/network-mock-tools.js.map +0 -1
  605. package/dist/input/network-mock.d.ts.map +0 -1
  606. package/dist/input/network-mock.js.map +0 -1
  607. package/dist/input/real-input.d.ts.map +0 -1
  608. package/dist/input/real-input.js.map +0 -1
  609. package/dist/input/scroll-find.d.ts.map +0 -1
  610. package/dist/input/scroll-find.js.map +0 -1
  611. package/dist/input/scroll-tools.d.ts.map +0 -1
  612. package/dist/input/scroll-tools.js.map +0 -1
  613. package/dist/input/viewport-tools.d.ts.map +0 -1
  614. package/dist/input/viewport-tools.js.map +0 -1
  615. package/dist/journal/ambient-store.d.ts.map +0 -1
  616. package/dist/journal/ambient-store.js.map +0 -1
  617. package/dist/journal/ambient.d.ts.map +0 -1
  618. package/dist/journal/ambient.js.map +0 -1
  619. package/dist/journal/attach-journal.d.ts.map +0 -1
  620. package/dist/journal/attach-journal.js.map +0 -1
  621. package/dist/journal/deviation-report.d.ts.map +0 -1
  622. package/dist/journal/deviation-report.js.map +0 -1
  623. package/dist/journal/deviation-service.d.ts.map +0 -1
  624. package/dist/journal/deviation-service.js.map +0 -1
  625. package/dist/journal/envelope-store.d.ts.map +0 -1
  626. package/dist/journal/envelope-store.js.map +0 -1
  627. package/dist/journal/envelope.d.ts.map +0 -1
  628. package/dist/journal/envelope.js.map +0 -1
  629. package/dist/journal/journal-query.d.ts.map +0 -1
  630. package/dist/journal/journal-query.js.map +0 -1
  631. package/dist/journal/journal-recorder.d.ts.map +0 -1
  632. package/dist/journal/journal-recorder.js.map +0 -1
  633. package/dist/journal/retention.d.ts.map +0 -1
  634. package/dist/journal/retention.js.map +0 -1
  635. package/dist/journal/rollups.d.ts.map +0 -1
  636. package/dist/journal/rollups.js.map +0 -1
  637. package/dist/journal/session-end.d.ts.map +0 -1
  638. package/dist/journal/session-end.js.map +0 -1
  639. package/dist/journal/session-journal.d.ts.map +0 -1
  640. package/dist/journal/session-journal.js.map +0 -1
  641. package/dist/license/license.d.ts.map +0 -1
  642. package/dist/license/license.js.map +0 -1
  643. package/dist/log.d.ts.map +0 -1
  644. package/dist/log.js.map +0 -1
  645. package/dist/mcp-proxy.d.ts.map +0 -1
  646. package/dist/mcp-proxy.js.map +0 -1
  647. package/dist/mcp.d.ts.map +0 -1
  648. package/dist/mcp.js.map +0 -1
  649. package/dist/oracles/flow-instrument-gaps.d.ts.map +0 -1
  650. package/dist/oracles/flow-instrument-gaps.js.map +0 -1
  651. package/dist/oracles/propose-consequences.d.ts.map +0 -1
  652. package/dist/oracles/propose-consequences.js.map +0 -1
  653. package/dist/oracles/self-instrument.d.ts.map +0 -1
  654. package/dist/oracles/self-instrument.js.map +0 -1
  655. package/dist/pairing-token.d.ts.map +0 -1
  656. package/dist/pairing-token.js.map +0 -1
  657. package/dist/phenomena/phenomena.d.ts.map +0 -1
  658. package/dist/phenomena/phenomena.js.map +0 -1
  659. package/dist/pool/browser-pool.d.ts.map +0 -1
  660. package/dist/pool/browser-pool.js.map +0 -1
  661. package/dist/pool/lease-reaper.d.ts.map +0 -1
  662. package/dist/pool/lease-reaper.js.map +0 -1
  663. package/dist/pool/playwright-launcher.d.ts.map +0 -1
  664. package/dist/pool/playwright-launcher.js.map +0 -1
  665. package/dist/project/baselines.d.ts.map +0 -1
  666. package/dist/project/baselines.js.map +0 -1
  667. package/dist/project/file-lock.d.ts.map +0 -1
  668. package/dist/project/file-lock.js.map +0 -1
  669. package/dist/project/fs-port.d.ts.map +0 -1
  670. package/dist/project/fs-port.js.map +0 -1
  671. package/dist/project/project-store.d.ts.map +0 -1
  672. package/dist/project/project-store.js.map +0 -1
  673. package/dist/project/project-tools.d.ts.map +0 -1
  674. package/dist/project/project-tools.js.map +0 -1
  675. package/dist/project/reticle-dir.d.ts.map +0 -1
  676. package/dist/project/reticle-dir.js.map +0 -1
  677. package/dist/runs/build-verification-run.d.ts.map +0 -1
  678. package/dist/runs/build-verification-run.js.map +0 -1
  679. package/dist/runs/profile-redact.d.ts.map +0 -1
  680. package/dist/runs/profile-redact.js.map +0 -1
  681. package/dist/runs/render-report.d.ts.map +0 -1
  682. package/dist/runs/render-report.js.map +0 -1
  683. package/dist/runs/repair-prompt.d.ts.map +0 -1
  684. package/dist/runs/repair-prompt.js.map +0 -1
  685. package/dist/runs/replay-mapping.d.ts.map +0 -1
  686. package/dist/runs/replay-mapping.js.map +0 -1
  687. package/dist/runs/reticle-runner.d.ts.map +0 -1
  688. package/dist/runs/reticle-runner.js.map +0 -1
  689. package/dist/runs/risk-classify.d.ts.map +0 -1
  690. package/dist/runs/risk-classify.js.map +0 -1
  691. package/dist/runs/run-diff.d.ts.map +0 -1
  692. package/dist/runs/run-diff.js.map +0 -1
  693. package/dist/runs/run-store.d.ts.map +0 -1
  694. package/dist/runs/run-store.js.map +0 -1
  695. package/dist/runs/run-tools.d.ts.map +0 -1
  696. package/dist/runs/run-tools.js.map +0 -1
  697. package/dist/runs/runner-port.d.ts.map +0 -1
  698. package/dist/runs/runner-port.js.map +0 -1
  699. package/dist/runs/verification-sync.d.ts.map +0 -1
  700. package/dist/runs/verification-sync.js.map +0 -1
  701. package/dist/runs/verify-http.d.ts.map +0 -1
  702. package/dist/runs/verify-http.js.map +0 -1
  703. package/dist/runs/verify-server.d.ts.map +0 -1
  704. package/dist/runs/verify-server.js.map +0 -1
  705. package/dist/server-version.d.ts.map +0 -1
  706. package/dist/server-version.js.map +0 -1
  707. package/dist/session/control-envelope.d.ts.map +0 -1
  708. package/dist/session/control-envelope.js.map +0 -1
  709. package/dist/session/live-control-tools.d.ts.map +0 -1
  710. package/dist/session/live-control-tools.js.map +0 -1
  711. package/dist/session/live-control.d.ts.map +0 -1
  712. package/dist/session/live-control.js.map +0 -1
  713. package/dist/session/observed-state.d.ts.map +0 -1
  714. package/dist/session/observed-state.js.map +0 -1
  715. package/dist/session/output-budget.d.ts.map +0 -1
  716. package/dist/session/output-budget.js.map +0 -1
  717. package/dist/session/presenter-args.d.ts.map +0 -1
  718. package/dist/session/presenter-args.js.map +0 -1
  719. package/dist/session/review-store.d.ts.map +0 -1
  720. package/dist/session/review-store.js.map +0 -1
  721. package/dist/session/session-health.d.ts.map +0 -1
  722. package/dist/session/session-health.js.map +0 -1
  723. package/dist/session/session-manager.d.ts.map +0 -1
  724. package/dist/session/session-manager.js.map +0 -1
  725. package/dist/session/session-readiness.d.ts.map +0 -1
  726. package/dist/session/session-readiness.js.map +0 -1
  727. package/dist/session/session-reaper.d.ts.map +0 -1
  728. package/dist/session/session-reaper.js.map +0 -1
  729. package/dist/session/session-recommendation.d.ts.map +0 -1
  730. package/dist/session/session-recommendation.js.map +0 -1
  731. package/dist/session/session-tools.d.ts.map +0 -1
  732. package/dist/session/session-tools.js.map +0 -1
  733. package/dist/session/session.d.ts.map +0 -1
  734. package/dist/session/session.js.map +0 -1
  735. package/dist/session/state-select.d.ts.map +0 -1
  736. package/dist/session/state-select.js.map +0 -1
  737. package/dist/telemetry/telemetry.d.ts.map +0 -1
  738. package/dist/telemetry/telemetry.js.map +0 -1
  739. package/dist/token-auth.d.ts.map +0 -1
  740. package/dist/token-auth.js.map +0 -1
  741. package/dist/tools/act-tools.d.ts.map +0 -1
  742. package/dist/tools/act-tools.js.map +0 -1
  743. package/dist/tools/act-view.d.ts.map +0 -1
  744. package/dist/tools/act-view.js.map +0 -1
  745. package/dist/tools/assert-grade.d.ts.map +0 -1
  746. package/dist/tools/assert-grade.js.map +0 -1
  747. package/dist/tools/browser-tools.d.ts.map +0 -1
  748. package/dist/tools/browser-tools.js.map +0 -1
  749. package/dist/tools/contract-tools.d.ts.map +0 -1
  750. package/dist/tools/contract-tools.js.map +0 -1
  751. package/dist/tools/dynamic-tools.d.ts.map +0 -1
  752. package/dist/tools/dynamic-tools.js.map +0 -1
  753. package/dist/tools/error-recovery.d.ts.map +0 -1
  754. package/dist/tools/error-recovery.js.map +0 -1
  755. package/dist/tools/invoke-tool.d.ts.map +0 -1
  756. package/dist/tools/invoke-tool.js.map +0 -1
  757. package/dist/tools/lease-tools.d.ts.map +0 -1
  758. package/dist/tools/lease-tools.js.map +0 -1
  759. package/dist/tools/merge-tools.d.ts.map +0 -1
  760. package/dist/tools/merge-tools.js.map +0 -1
  761. package/dist/tools/observe-tools.d.ts.map +0 -1
  762. package/dist/tools/observe-tools.js.map +0 -1
  763. package/dist/tools/profiles.d.ts.map +0 -1
  764. package/dist/tools/profiles.js.map +0 -1
  765. package/dist/tools/query-paginate.d.ts.map +0 -1
  766. package/dist/tools/query-paginate.js.map +0 -1
  767. package/dist/tools/read-tools.d.ts.map +0 -1
  768. package/dist/tools/read-tools.js.map +0 -1
  769. package/dist/tools/snapshot-delta.d.ts.map +0 -1
  770. package/dist/tools/snapshot-delta.js.map +0 -1
  771. package/dist/tools/tool-invoker.d.ts.map +0 -1
  772. package/dist/tools/tool-invoker.js.map +0 -1
  773. package/dist/tools/tool-kit.d.ts.map +0 -1
  774. package/dist/tools/tool-kit.js.map +0 -1
  775. package/dist/tools/tool-names.d.ts.map +0 -1
  776. package/dist/tools/tool-names.js.map +0 -1
  777. package/dist/tools/tools-helpers.d.ts.map +0 -1
  778. package/dist/tools/tools-helpers.js.map +0 -1
  779. package/dist/tools/tools.d.ts.map +0 -1
  780. package/dist/tools/tools.js.map +0 -1
  781. package/dist/update/update-checker.d.ts.map +0 -1
  782. package/dist/update/update-checker.js.map +0 -1
  783. package/dist/update/updater.d.ts.map +0 -1
  784. package/dist/update/updater.js.map +0 -1
  785. package/dist/visual/visual-diff.d.ts.map +0 -1
  786. package/dist/visual/visual-diff.js.map +0 -1
  787. package/dist/visual/visual-store.d.ts.map +0 -1
  788. package/dist/visual/visual-store.js.map +0 -1
  789. package/dist/visual/visual-tools.d.ts.map +0 -1
  790. package/dist/visual/visual-tools.js.map +0 -1
@@ -0,0 +1,4 @@
1
+ import { type ReticleEvent } from '@reticlehq/core';
2
+ import type { Contradiction } from './contradictions.js';
3
+ /** The one contradiction, or none. Reported once per window — a race is a fact about the window. */
4
+ export declare function findStaleResponses(events: readonly ReticleEvent[]): Contradiction[];
@@ -0,0 +1,139 @@
1
+ import { ContradictionKind, EventType } from '@reticlehq/core';
2
+ function pathOf(url) {
3
+ const q = url.indexOf('?');
4
+ return q === -1 ? url : url.slice(0, q);
5
+ }
6
+ function queryOf(url) {
7
+ const q = url.indexOf('?');
8
+ return q === -1 ? '' : url.slice(q + 1);
9
+ }
10
+ /**
11
+ * Parameters that ENUMERATE a collection rather than select within it.
12
+ *
13
+ * Two overlapping reads that differ only in these are a fan-out, not a race: an app fetching page 0
14
+ * and page 5 in parallel wants both, and whichever lands last is not overwriting the other. Measured
15
+ * against a synthetic dashboard doing parallel pagination — every run reported a race, because the
16
+ * requests do overlap and do settle out of order, and the original rule looked no further than that.
17
+ *
18
+ * A filter race differs in a SELECTING parameter (`status`, `q`, a date range): the second request
19
+ * makes the first obsolete, both answer into the same view, and the slower one wins.
20
+ */
21
+ const ENUMERATING_PARAMS = new Set([
22
+ 'page',
23
+ 'offset',
24
+ 'cursor',
25
+ 'limit',
26
+ 'size',
27
+ 'per_page',
28
+ 'perPage',
29
+ 'pageSize',
30
+ 'after',
31
+ 'before',
32
+ 'start',
33
+ 'end',
34
+ ]);
35
+ /** Whether the two queries differ ONLY in how much of the same collection they ask for. */
36
+ function differsOnlyByEnumeration(first, second) {
37
+ const a = new URLSearchParams(first);
38
+ const b = new URLSearchParams(second);
39
+ const keys = new Set([...a.keys(), ...b.keys()]);
40
+ let differed = false;
41
+ for (const key of keys) {
42
+ if (a.get(key) === b.get(key))
43
+ continue;
44
+ if (!ENUMERATING_PARAMS.has(key))
45
+ return false;
46
+ differed = true;
47
+ }
48
+ return differed;
49
+ }
50
+ /** Pair NET_PENDING with its NET_REQUEST by the id both carry. Unpaired events are still in flight. */
51
+ function flights(events) {
52
+ const issued = new Map();
53
+ const out = [];
54
+ for (const event of events) {
55
+ const id = typeof event.data['id'] === 'string' ? event.data['id'] : undefined;
56
+ if (id === undefined)
57
+ continue;
58
+ const at = typeof event.t === 'number' ? event.t : 0;
59
+ if (event.type === EventType.NET_PENDING) {
60
+ const url = typeof event.data['url'] === 'string' ? event.data['url'] : '';
61
+ const method = typeof event.data['method'] === 'string' ? event.data['method'] : 'GET';
62
+ issued.set(id, { url, method, at });
63
+ continue;
64
+ }
65
+ if (event.type !== EventType.NET_REQUEST)
66
+ continue;
67
+ const start = issued.get(id);
68
+ if (start === undefined)
69
+ continue; // started before this window — its ordering is unknowable
70
+ out.push({
71
+ id,
72
+ url: start.url,
73
+ method: start.method.toUpperCase(),
74
+ issuedAt: start.at,
75
+ settledAt: at,
76
+ });
77
+ }
78
+ return out;
79
+ }
80
+ /**
81
+ * Most recent flights compared per endpoint.
82
+ *
83
+ * The comparison is pairwise, so an unbounded window is quadratic: measured at 548ms for 2000
84
+ * concurrent reads of one endpoint, paid on EVERY verdict. A verdict that costs half a second is a
85
+ * verdict agents stop asking for. Racing requests are adjacent in time by definition, so the most
86
+ * recent flights are where a race can be; older ones cannot overlap them anyway.
87
+ *
88
+ * Bounded rather than silent: this is a detection ceiling, not a truncation of reported data — a race
89
+ * among more than this many simultaneous reads of ONE endpoint goes unreported, and that is a
90
+ * deliberate trade for a hot path that runs on every assert.
91
+ */
92
+ const MAX_FLIGHTS_PER_PATH = 60;
93
+ /** The one contradiction, or none. Reported once per window — a race is a fact about the window. */
94
+ export function findStaleResponses(events) {
95
+ // Grouped by path first: two reads of DIFFERENT endpoints can never race, and comparing them was
96
+ // the bulk of the work on any real page, which talks to many endpoints at once.
97
+ const byPath = new Map();
98
+ for (const flight of flights(events)) {
99
+ if (flight.method !== 'GET')
100
+ continue;
101
+ const path = pathOf(flight.url);
102
+ const group = byPath.get(path) ?? [];
103
+ group.push(flight);
104
+ byPath.set(path, group);
105
+ }
106
+ for (const group of byPath.values()) {
107
+ const reads = group.slice(-MAX_FLIGHTS_PER_PATH);
108
+ const found = raceIn(reads);
109
+ if (found !== undefined)
110
+ return [found];
111
+ }
112
+ return [];
113
+ }
114
+ function raceIn(reads) {
115
+ for (const first of reads) {
116
+ for (const second of reads) {
117
+ if (first.id === second.id)
118
+ continue;
119
+ if (second.issuedAt <= first.issuedAt)
120
+ continue; // `first` must be the earlier request
121
+ if (second.issuedAt >= first.settledAt)
122
+ continue; // sequential, not overlapping
123
+ if (second.settledAt >= first.settledAt)
124
+ continue; // settled in order — no race
125
+ if (queryOf(first.url) === queryOf(second.url))
126
+ continue; // a retry, not a superseding query
127
+ // Parallel pagination is not a race — see differsOnlyByEnumeration.
128
+ if (differsOnlyByEnumeration(queryOf(first.url), queryOf(second.url)))
129
+ continue;
130
+ return {
131
+ kind: ContradictionKind.STALE_RESPONSE_APPLIED,
132
+ claim: `both reads of ${pathOf(first.url)} returned successfully and the page settled`,
133
+ counter: `the SUPERSEDED request (${queryOf(first.url)}) settled ${String(Math.max(0, first.settledAt - second.settledAt))}ms AFTER the one that replaced it (${queryOf(second.url)}), so the screen is showing the older query's data`,
134
+ detail: 'a filter/search race: the newer request was issued while the older was still in flight, and the older answered last, so whichever query the server happens to be slower at wins — unless the app cancels superseded requests or drops responses that no longer match current state',
135
+ };
136
+ }
137
+ }
138
+ return undefined;
139
+ }
@@ -0,0 +1,16 @@
1
+ import { type ReticleEvent } from '@reticlehq/core';
2
+ import type { Contradiction } from './contradictions.js';
3
+ /**
4
+ * @param prior events from BEFORE the window, used only to learn what the API has stated.
5
+ *
6
+ * The scale error is a disagreement with a value the API gave EARLIER — by definition before the
7
+ * action that sends it back. `reticle_assert` scopes its window to the last act's cursor, so the
8
+ * stating response falls outside it and `known` is empty exactly when it matters. Measured live on
9
+ * the payments panel: `reticle_observe` over a wide window reported the mismatch while `assert` on
10
+ * the same session reported none — the verdict tool, the one an agent gates on, was the blind one.
11
+ *
12
+ * Prior events TEACH, they are never themselves findings: widening the window instead would make
13
+ * every other rule blame this action for events it did not cause, and would re-report every earlier
14
+ * mistake on every assert.
15
+ */
16
+ export declare function findUnitMismatches(events: readonly ReticleEvent[], prior?: readonly ReticleEvent[]): Contradiction[];
@@ -0,0 +1,167 @@
1
+ import { ContradictionKind, EventType } from '@reticlehq/core';
2
+ /**
3
+ * The app sent a money value back in a DIFFERENT unit than the API gave it.
4
+ *
5
+ * Payment APIs overwhelmingly speak minor units — Stripe, Razorpay, Adyen, PayPal all state amounts
6
+ * in paise/cents as integers. A UI renders that as a major-unit string, and the bug is writing the
7
+ * rendered number back into the field the integer came from.
8
+ *
9
+ * Measured on a real payments dashboard: `GET /payments` returns `amount: 118701` for a payment, the
10
+ * row renders "₹1,187.01", and the refund posts `{"amount": 1187.01}` into the same field. The server
11
+ * takes 1187 paise and answers `200 {"status": "processed"}`. That is a 100x UNDER-REFUND, and every
12
+ * channel agrees it worked: the status is 200, the payload says processed, the UI advances, the page
13
+ * settles, and the number in the request is exactly the number on the screen. Nothing disagrees,
14
+ * because the disagreement is with a value the API returned EARLIER in the session.
15
+ *
16
+ * Which is the point: this is only visible to something holding the whole request timeline with
17
+ * bodies. A snapshot cannot see it, a status column cannot see it, and a human reading the request
18
+ * sees the amount they expected.
19
+ *
20
+ * Not a heuristic about decimals. Firing on "an amount had a fractional part" would accuse every API
21
+ * that legitimately uses major units. This fires only when the SAME field of the SAME entity was
22
+ * observed at a different scale — a comparison, not a guess.
23
+ */
24
+ /** Fields worth comparing. Deliberately short: money, not every number an app sends. */
25
+ const MONEY_FIELDS = new Set(['amount', 'value', 'price', 'total', 'fee', 'cost', 'balance']);
26
+ /**
27
+ * Scales that indicate a minor/major confusion. 100 covers two-decimal currencies; 1000 covers the
28
+ * three-decimal ones (KWD, BHD, JOD, TND).
29
+ */
30
+ const SCALES = [100, 1000];
31
+ /**
32
+ * Prefixed ids (`pay_NkT10001`) and uuids, matched anywhere in a URL or a string field.
33
+ *
34
+ * Numeric ids are handled separately by path segment: `/api/orders/9/capture` is at least as common
35
+ * as a prefixed id, and a bare `9` cannot be pattern-matched out of arbitrary text without matching
36
+ * every other number too.
37
+ */
38
+ const ID_PATTERN = /[A-Za-z]{2,}_[A-Za-z0-9]{2,}|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}/g;
39
+ function parse(raw) {
40
+ if (typeof raw !== 'string' || raw.length === 0)
41
+ return undefined;
42
+ try {
43
+ return JSON.parse(raw);
44
+ }
45
+ catch {
46
+ return undefined;
47
+ }
48
+ }
49
+ /** Every (id, field, value) triple in a payload, from objects that carry an id of their own. */
50
+ function moneyByEntity(node, into) {
51
+ if (Array.isArray(node)) {
52
+ for (const item of node)
53
+ moneyByEntity(item, into);
54
+ return;
55
+ }
56
+ if (typeof node !== 'object' || node === null)
57
+ return;
58
+ const record = node;
59
+ // An id may arrive as a number (`{"id": 9}`) — normalised so a numeric path segment matches it.
60
+ const raw = record['id'];
61
+ const id = typeof raw === 'string' ? raw : typeof raw === 'number' ? String(raw) : undefined;
62
+ if (id !== undefined) {
63
+ for (const [key, value] of Object.entries(record)) {
64
+ if (!MONEY_FIELDS.has(key) || typeof value !== 'number')
65
+ continue;
66
+ const fields = into.get(id) ?? new Map();
67
+ fields.set(key, value);
68
+ into.set(id, fields);
69
+ }
70
+ }
71
+ for (const value of Object.values(record))
72
+ moneyByEntity(value, into);
73
+ }
74
+ /** Ids named anywhere in a URL or a request payload — how a write says which entity it targets. */
75
+ function idsIn(url, body) {
76
+ const found = new Set(url.match(ID_PATTERN) ?? []);
77
+ // Numeric path segments: `/api/orders/9/capture` names entity 9.
78
+ for (const segment of url.split('?')[0]?.split('/') ?? []) {
79
+ if (segment.length > 0 && /^\d+$/.test(segment))
80
+ found.add(segment);
81
+ }
82
+ if (typeof body === 'object' && body !== null) {
83
+ for (const value of Object.values(body)) {
84
+ if (typeof value === 'string')
85
+ for (const id of value.match(ID_PATTERN) ?? [])
86
+ found.add(id);
87
+ }
88
+ }
89
+ return Array.from(found);
90
+ }
91
+ /** The scale between a known value and a sent one, or undefined when they are consistent. */
92
+ function scaleBetween(known, sent) {
93
+ if (sent === 0 || known === 0)
94
+ return undefined;
95
+ for (const scale of SCALES) {
96
+ // A tolerance, because the major-unit form is a rounded render of the minor one.
97
+ if (Math.abs(known - sent * scale) <= scale / 2)
98
+ return scale;
99
+ }
100
+ return undefined;
101
+ }
102
+ /**
103
+ * @param prior events from BEFORE the window, used only to learn what the API has stated.
104
+ *
105
+ * The scale error is a disagreement with a value the API gave EARLIER — by definition before the
106
+ * action that sends it back. `reticle_assert` scopes its window to the last act's cursor, so the
107
+ * stating response falls outside it and `known` is empty exactly when it matters. Measured live on
108
+ * the payments panel: `reticle_observe` over a wide window reported the mismatch while `assert` on
109
+ * the same session reported none — the verdict tool, the one an agent gates on, was the blind one.
110
+ *
111
+ * Prior events TEACH, they are never themselves findings: widening the window instead would make
112
+ * every other rule blame this action for events it did not cause, and would re-report every earlier
113
+ * mistake on every assert.
114
+ */
115
+ export function findUnitMismatches(events, prior = []) {
116
+ // What the API has told us about each entity so far, in the API's own units.
117
+ const known = new Map();
118
+ for (const event of prior) {
119
+ if (event.type !== EventType.NET_REQUEST)
120
+ continue;
121
+ const body = parse(event.data['responseBody']);
122
+ if (body !== undefined)
123
+ moneyByEntity(body, known);
124
+ }
125
+ const found = [];
126
+ const seen = new Set();
127
+ for (const event of events) {
128
+ if (event.type !== EventType.NET_REQUEST)
129
+ continue;
130
+ const url = typeof event.data['url'] === 'string' ? event.data['url'] : '';
131
+ const requestBody = parse(event.data['requestBody']);
132
+ // Compare BEFORE recording this call's own response, or a request that echoes its own reply
133
+ // would compare against itself.
134
+ if (typeof requestBody === 'object' && requestBody !== null) {
135
+ const sentFields = requestBody;
136
+ for (const id of idsIn(url, requestBody)) {
137
+ const fields = known.get(id);
138
+ if (fields === undefined)
139
+ continue;
140
+ for (const [key, sent] of Object.entries(sentFields)) {
141
+ if (!MONEY_FIELDS.has(key) || typeof sent !== 'number')
142
+ continue;
143
+ const priorValue = fields.get(key);
144
+ if (priorValue === undefined)
145
+ continue;
146
+ const scale = scaleBetween(priorValue, sent);
147
+ if (scale === undefined)
148
+ continue;
149
+ const key2 = `${id}:${key}`;
150
+ if (seen.has(key2))
151
+ continue;
152
+ seen.add(key2);
153
+ found.push({
154
+ kind: ContradictionKind.UNIT_MISMATCH,
155
+ claim: `the request sent ${key}=${String(sent)} and the server accepted it`,
156
+ counter: `the API reports ${key}=${String(priorValue)} for ${id} — the value sent is ${String(scale)}x SMALLER, i.e. a major-unit number written into a minor-unit field`,
157
+ detail: `${url} — at this scale the operation moves ${String(sent)} minor units instead of ${String(priorValue)}; nothing else can see this, because the number sent is exactly the number rendered on screen`,
158
+ });
159
+ }
160
+ }
161
+ }
162
+ const responseBody = parse(event.data['responseBody']);
163
+ if (responseBody !== undefined)
164
+ moneyByEntity(responseBody, known);
165
+ }
166
+ return found;
167
+ }
@@ -0,0 +1,18 @@
1
+ import type { ToolDef } from '../tools/tools.js';
2
+ /**
3
+ * `reticle_affected` — which saved flows must re-verify for a set of changed files.
4
+ *
5
+ * This logic already existed as `reticle affected`, deliberately kept off the MCP surface because an
6
+ * advertised tool costs tokens on every turn whether or not it is used. That reasoning is right, and
7
+ * this does not change it: the tool is NOT advertised by any profile. It is reachable through
8
+ * `reticle_run`, so it costs nothing per turn and is still discoverable via `reticle_tools`.
9
+ *
10
+ * What the reasoning missed is who holds the question. The AGENT is the one that just edited files
11
+ * and has to decide what to re-check; a shell command it may not be able to run is not an answer for
12
+ * an MCP client that has no shell. Leaving it CLI-only meant the party with the diff could not ask
13
+ * the party with the index.
14
+ *
15
+ * Unknown-provenance flows are returned as affected (fail-safe) AND listed separately, so "re-verify
16
+ * this" is never confused with "this definitely touches your change".
17
+ */
18
+ export declare const AFFECTED_TOOLS: ToolDef[];
@@ -0,0 +1,52 @@
1
+ import { z } from 'zod';
2
+ import { ReticleTool } from '../tools/tool-names.js';
3
+ import { loadNamedFlows, resolveChangedFiles } from '../cli-flow-commands.js';
4
+ import { affectedSavedFlows } from './flow-sources.js';
5
+ /**
6
+ * `reticle_affected` — which saved flows must re-verify for a set of changed files.
7
+ *
8
+ * This logic already existed as `reticle affected`, deliberately kept off the MCP surface because an
9
+ * advertised tool costs tokens on every turn whether or not it is used. That reasoning is right, and
10
+ * this does not change it: the tool is NOT advertised by any profile. It is reachable through
11
+ * `reticle_run`, so it costs nothing per turn and is still discoverable via `reticle_tools`.
12
+ *
13
+ * What the reasoning missed is who holds the question. The AGENT is the one that just edited files
14
+ * and has to decide what to re-check; a shell command it may not be able to run is not an answer for
15
+ * an MCP client that has no shell. Leaving it CLI-only meant the party with the diff could not ask
16
+ * the party with the index.
17
+ *
18
+ * Unknown-provenance flows are returned as affected (fail-safe) AND listed separately, so "re-verify
19
+ * this" is never confused with "this definitely touches your change".
20
+ */
21
+ export const AFFECTED_TOOLS = [
22
+ {
23
+ name: ReticleTool.AFFECTED,
24
+ description: 'Which saved flows must re-verify for a set of changed files. Pass the files you edited (and/or `since` for a git ref to diff against). Returns { changedFiles, affected, unknownProvenance } — `affected` is what to re-run, and `unknownProvenance` are flows included only because Reticle cannot tell which sources they cover, so they are re-verified by default rather than silently skipped.',
25
+ example: { files: ['src/App.tsx'] },
26
+ inputSchema: {
27
+ files: z
28
+ .array(z.string())
29
+ .optional()
30
+ .describe('Changed file paths, repo-relative (e.g. ["src/App.tsx"]).'),
31
+ since: z
32
+ .string()
33
+ .optional()
34
+ .describe('Git ref to diff against (e.g. "HEAD~1", "main"). Unioned with `files`.'),
35
+ },
36
+ outputSchema: {
37
+ changedFiles: z.array(z.string()),
38
+ affected: z.array(z.string()),
39
+ unknownProvenance: z.array(z.string()),
40
+ },
41
+ handler: async (deps, args) => {
42
+ const files = Array.isArray(args['files'])
43
+ ? args['files'].filter((f) => typeof f === 'string')
44
+ : [];
45
+ const since = typeof args['since'] === 'string' ? args['since'] : undefined;
46
+ const changedFiles = await resolveChangedFiles(files, since);
47
+ const flows = await loadNamedFlows(deps.fs, deps.reticleRoot);
48
+ const result = affectedSavedFlows(flows, changedFiles);
49
+ return { changedFiles, ...result };
50
+ },
51
+ },
52
+ ];
@@ -22,4 +22,3 @@ export interface AffectedResult {
22
22
  * a repo-relative change matches an absolute stamp and vice-versa.
23
23
  */
24
24
  export declare function affectedFlows(flows: readonly FlowSources[], changedFiles: readonly string[]): AffectedResult;
25
- //# sourceMappingURL=affected.d.ts.map
@@ -33,4 +33,3 @@ export function affectedFlows(flows, changedFiles) {
33
33
  }
34
34
  return { affected, unknownProvenance };
35
35
  }
36
- //# sourceMappingURL=affected.js.map
@@ -13,4 +13,3 @@ import type { ToolDef } from '../tools/tools.js';
13
13
  * agent that annotates at the wrong moment gets a clear error rather than a crash.
14
14
  */
15
15
  export declare const ANNOTATE_TOOLS: ToolDef[];
16
- //# sourceMappingURL=annotate-tools.d.ts.map
@@ -1,5 +1,14 @@
1
1
  import { z } from 'zod';
2
2
  import { AnnotationErrorCode, AnnotationSchema } from '@reticlehq/core';
3
+ import { RECOVERY } from '../tools/error-recovery.js';
4
+ /**
5
+ * An unknown kind is almost always a free-text annotation, which this tool deliberately refuses to
6
+ * guess into a predicate. Naming the six kinds turns a dead end into one retry.
7
+ */
8
+ const UNKNOWN_KIND_RECOVERY = 'Annotations are structured, never free text. Pass one of: ' +
9
+ '{ kind: "assert-signal", name }, { kind: "assert-visible", testid }, ' +
10
+ '{ kind: "assert-state", statePath }, { kind: "mark-dynamic", testid }, ' +
11
+ '{ kind: "success-state", signal|testid }, or { kind: "intent", text }.';
3
12
  import { ReticleTool } from '../tools/tool-names.js';
4
13
  import { asString } from '../tools/tools-helpers.js';
5
14
  import { compileAnnotation } from './annotate.js';
@@ -20,6 +29,7 @@ const DEFAULT_RECORDING = 'default';
20
29
  export const ANNOTATE_TOOLS = [
21
30
  {
22
31
  name: ReticleTool.ANNOTATE,
32
+ example: { kind: 'assert-signal', name: 'todos:loaded' },
23
33
  description: 'Attach a STRUCTURED annotation to the active recording, compiling it into the flow. kind: ' +
24
34
  'assert-signal { name, dataMatches? } → the last step asserts that signal; assert-visible ' +
25
35
  '{ testid } → the last step asserts that element is present; assert-state ' +
@@ -98,6 +108,7 @@ export const ANNOTATE_TOOLS = [
98
108
  },
99
109
  outputSchema: {
100
110
  ok: z.boolean(),
111
+ recovery: z.string().optional(),
101
112
  target: z.string().optional(),
102
113
  compiled: z.string().optional(),
103
114
  code: z.string().optional(),
@@ -107,12 +118,20 @@ export const ANNOTATE_TOOLS = [
107
118
  // Structured boundary: a free NL string / unknown kind fails the schema → UNKNOWN_KIND.
108
119
  const parsed = AnnotationSchema.safeParse(args);
109
120
  if (!parsed.success) {
110
- return Promise.resolve({ ok: false, code: AnnotationErrorCode.UNKNOWN_KIND });
121
+ return Promise.resolve({
122
+ ok: false,
123
+ code: AnnotationErrorCode.UNKNOWN_KIND,
124
+ recovery: UNKNOWN_KIND_RECOVERY,
125
+ });
111
126
  }
112
127
  const stepCount = deps.recordings.stepCount(name);
113
128
  const compiled = deps.recordings.getCompiled(name) !== undefined;
114
129
  if (stepCount === undefined && !compiled) {
115
- return Promise.resolve({ ok: false, code: AnnotationErrorCode.NO_ACTIVE_RECORDING });
130
+ return Promise.resolve({
131
+ ok: false,
132
+ code: AnnotationErrorCode.NO_ACTIVE_RECORDING,
133
+ recovery: RECOVERY.MISSING_RECORDING,
134
+ });
116
135
  }
117
136
  const outcome = compileAnnotation(parsed.data, stepCount ?? 0);
118
137
  if (!outcome.result.ok)
@@ -133,4 +152,3 @@ export const ANNOTATE_TOOLS = [
133
152
  },
134
153
  },
135
154
  ];
136
- //# sourceMappingURL=annotate-tools.js.map
@@ -19,4 +19,3 @@ export declare function compileAnnotation(a: Annotation, stepCount: number): Ann
19
19
  * e.g. `will assert signal diff:shown`. The leading word is the named COMPILED_PREDICATE_PREFIX.
20
20
  */
21
21
  export declare function describeCompiled(a: Annotation): string;
22
- //# sourceMappingURL=annotate.d.ts.map
@@ -131,4 +131,3 @@ export function describeCompiled(a) {
131
131
  return `${COMPILED_PREDICATE_PREFIX} intent: ${a.text}`;
132
132
  }
133
133
  }
134
- //# sourceMappingURL=annotate.js.map
@@ -20,4 +20,3 @@ export declare class AnnotationStore {
20
20
  /** Drop a recording's annotations (called after reticle_flow_save folds them onto disk). */
21
21
  clear(name: string): void;
22
22
  }
23
- //# sourceMappingURL=annotation-store.d.ts.map
@@ -48,4 +48,3 @@ export class AnnotationStore {
48
48
  this.#byName.delete(name);
49
49
  }
50
50
  }
51
- //# sourceMappingURL=annotation-store.js.map
@@ -21,4 +21,3 @@ export interface DowngradeFinding {
21
21
  * lives with the affected index.
22
22
  */
23
23
  export declare function detectDowngrades(before: readonly StepExpect[], after: readonly StepExpect[]): DowngradeFinding[];
24
- //# sourceMappingURL=assertion-integrity.d.ts.map
@@ -24,4 +24,3 @@ export function detectDowngrades(before, after) {
24
24
  }
25
25
  return findings;
26
26
  }
27
- //# sourceMappingURL=assertion-integrity.js.map
@@ -77,4 +77,3 @@ export declare class AssertionTiersStore {
77
77
  /** Record one flow's assertion shape + covered sources after it PASSED. Never breaks a replay. */
78
78
  recordPassing(name: string, steps: readonly StepExpect[], sources?: readonly string[]): Promise<void>;
79
79
  }
80
- //# sourceMappingURL=assertion-tiers-store.d.ts.map
@@ -96,4 +96,3 @@ export class AssertionTiersStore {
96
96
  }
97
97
  }
98
98
  }
99
- //# sourceMappingURL=assertion-tiers-store.js.map
@@ -22,4 +22,3 @@ export interface BuddyStatusInput {
22
22
  * `✗ 2 deviations: checkout, billing · 39 nominal · 1 flaky quarantined`
23
23
  */
24
24
  export declare function formatBuddyStatus(input: BuddyStatusInput): string;
25
- //# sourceMappingURL=buddy-status.d.ts.map
@@ -30,4 +30,3 @@ export function formatBuddyStatus(input) {
30
30
  }
31
31
  return parts.join(' · ');
32
32
  }
33
- //# sourceMappingURL=buddy-status.js.map
@@ -25,4 +25,3 @@ export interface Coverage {
25
25
  overallPct: number;
26
26
  }
27
27
  export declare function computeCoverage(declared: DeclaredSurface, exercised: DeclaredSurface): Coverage;
28
- //# sourceMappingURL=coverage.d.ts.map
@@ -19,4 +19,3 @@ export function computeCoverage(declared, exercised) {
19
19
  const overallPct = total === 0 ? 100 : Math.round((covered / total) * 100);
20
20
  return { testids, signals, flows, overallPct };
21
21
  }
22
- //# sourceMappingURL=coverage.js.map
@@ -1,13 +1,6 @@
1
1
  import { type FlowFile, type FlowReplayResult, type ReplayDecision, type SuiteVerdict } from '@reticlehq/core';
2
2
  export declare function buildDecision(result: FlowReplayResult, flow?: FlowFile): ReplayDecision;
3
- /**
4
- * Aggregate per-flow replays into one suite verdict — the autonomous loop's consolidated answer
5
- * after a build: did anything break, and what's the prioritized fix list. Pure: pass the already
6
- * decision-annotated replay results + their flows. Passing flows are counted; only failures carry
7
- * detail (token-cheap), each with the actionable decision so the agent fixes without re-querying.
8
- */
9
3
  export declare function buildSuiteVerdict(runs: ReadonlyArray<{
10
4
  replay: FlowReplayResult;
11
5
  flow?: FlowFile;
12
6
  }>): SuiteVerdict;
13
- //# sourceMappingURL=decision.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { AnchorKind, ReplayStatus, } from '@reticlehq/core';
2
- import { classifyFlowAssertions } from './flow-classify.js';
2
+ import { classifyFlowAssertions, FlowAssertionGrade } from './flow-classify.js';
3
3
  import { SUCCESS_STEP_TOOL } from './flow-success.js';
4
4
  /**
5
5
  * Turn a replay result into the autonomy DECISION envelope — the judgement a human reviewer used to
@@ -92,12 +92,39 @@ function suiteVerdictOf(status) {
92
92
  * decision-annotated replay results + their flows. Passing flows are counted; only failures carry
93
93
  * detail (token-cheap), each with the actionable decision so the agent fixes without re-querying.
94
94
  */
95
+ /**
96
+ * Why a green replay still verified nothing, or undefined when it genuinely did.
97
+ *
98
+ * A flow with no steps, or one that asserts no observable consequence, replays green no matter what
99
+ * the app does — the grader already knows this at save time and says so. Counting it as `passed`
100
+ * turned that warning into "all 1 flow pass", which is a false green in the exact feature sold as
101
+ * the regression suite. Classified only when the flow file is available; never guessed.
102
+ */
103
+ function unverifiableReason(flow) {
104
+ if (flow === undefined)
105
+ return undefined;
106
+ if (flow.steps.length === 0) {
107
+ return 'the flow has no steps — it replays green whatever the app does. Record it again, or add steps with reticle_annotate.';
108
+ }
109
+ const c = classifyFlowAssertions(flow);
110
+ if (c.grade !== FlowAssertionGrade.ASSERTION_FREE)
111
+ return undefined;
112
+ return (c.warning ??
113
+ 'the flow asserts no observable consequence, so it passes even when the feature is broken.');
114
+ }
95
115
  export function buildSuiteVerdict(runs) {
96
116
  const failures = [];
117
+ const unverifiable = [];
97
118
  let passed = 0;
98
119
  for (const { replay, flow } of runs) {
99
120
  if (replay.status === ReplayStatus.OK) {
100
- passed += 1;
121
+ const reason = unverifiableReason(flow);
122
+ // A green that cannot go red is not a pass. Counted apart, so `passed` stays a count of things
123
+ // actually verified rather than of replays that merely completed.
124
+ if (reason !== undefined)
125
+ unverifiable.push({ flow: replay.name, reason });
126
+ else
127
+ passed += 1;
101
128
  continue;
102
129
  }
103
130
  const decision = replay.decision ?? buildDecision(replay, flow);
@@ -111,10 +138,23 @@ export function buildSuiteVerdict(runs) {
111
138
  }
112
139
  const total = runs.length;
113
140
  const failed = failures.length;
114
- const status = failed === 0 ? 'pass' : 'fail';
141
+ // A real failure outranks an unverifiable flow: a broken flow is worse news than an empty one.
142
+ const status = failed > 0 ? 'fail' : unverifiable.length > 0 ? 'unverifiable' : 'pass';
143
+ const cannotFail = unverifiable.length === 0
144
+ ? ''
145
+ : ` — ${String(unverifiable.length)} verified nothing (${unverifiable.map((u) => u.flow).join(', ')})`;
115
146
  const summary = failed === 0
116
- ? `all ${total} flow${total === 1 ? '' : 's'} pass`
117
- : `${passed}/${total} flows pass — ${failed} need attention: ${failures.map((f) => f.flow).join(', ')}`;
118
- return { status, total, passed, failed, summary, failures };
147
+ ? unverifiable.length === 0
148
+ ? `all ${total} flow${total === 1 ? '' : 's'} pass`
149
+ : `${String(passed)}/${String(total)} flows verified${cannotFail}`
150
+ : `${passed}/${total} flows pass — ${failed} need attention: ${failures.map((f) => f.flow).join(', ')}${cannotFail}`;
151
+ return {
152
+ status,
153
+ total,
154
+ passed,
155
+ failed,
156
+ summary,
157
+ failures,
158
+ ...(unverifiable.length > 0 ? { unverifiable } : {}),
159
+ };
119
160
  }
120
- //# sourceMappingURL=decision.js.map
@@ -17,4 +17,3 @@ export declare class FlakeStore {
17
17
  /** The flows currently quarantined as flaky — what the gate excludes from blocking. */
18
18
  flakyFlows(): Promise<string[]>;
19
19
  }
20
- //# sourceMappingURL=flake-store.d.ts.map