@reticlehq/server 2.4.0 → 2.5.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 (416) hide show
  1. package/SKILL.md +702 -0
  2. package/dist/bridge/auth-failure-reason.d.ts +19 -0
  3. package/dist/bridge/auth-failure-reason.js +29 -0
  4. package/dist/{bridge-security.d.ts → bridge/bridge-security.d.ts} +1 -1
  5. package/dist/{bridge-security.js → bridge/bridge-security.js} +1 -1
  6. package/dist/{bridge.d.ts → bridge/bridge.d.ts} +1 -1
  7. package/dist/{bridge.js → bridge/bridge.js} +63 -13
  8. package/dist/{bridge.test-harness.d.ts → bridge/bridge.test-harness.d.ts} +1 -11
  9. package/dist/{bridge.test-harness.js → bridge/bridge.test-harness.js} +9 -9
  10. package/dist/{pairing-token.js → bridge/pairing-token.js} +1 -1
  11. package/dist/capsule/capsule-store.d.ts +8 -3
  12. package/dist/capsule/capsule-store.js +7 -2
  13. package/dist/capsule/capsule.js +3 -3
  14. package/dist/capsule/causal-summary.d.ts +8 -0
  15. package/dist/capsule/causal-summary.js +22 -12
  16. package/dist/capsule/divergence.d.ts +9 -4
  17. package/dist/capsule/divergence.js +8 -8
  18. package/dist/capsule/predicate-to-links.js +11 -8
  19. package/dist/{cli-doctor.js → cli/cli-doctor.js} +9 -2
  20. package/dist/{cli-flow-commands.d.ts → cli/cli-flow-commands.d.ts} +2 -2
  21. package/dist/{cli-flow-commands.js → cli/cli-flow-commands.js} +15 -15
  22. package/dist/{cli-launch.d.ts → cli/cli-launch.d.ts} +32 -3
  23. package/dist/cli/cli-launch.js +171 -0
  24. package/dist/{cli-parse.d.ts → cli/cli-parse.d.ts} +2 -11
  25. package/dist/{cli-parse.js → cli/cli-parse.js} +113 -60
  26. package/dist/{cli-port.d.ts → cli/cli-port.d.ts} +12 -0
  27. package/dist/{cli-port.js → cli/cli-port.js} +9 -9
  28. package/dist/cli/cli-update-commands.d.ts +4 -0
  29. package/dist/cli/cli-update-commands.js +93 -0
  30. package/dist/{cli-verify.js → cli/cli-verify.js} +14 -14
  31. package/dist/{cloud-cli.js → cli/cloud-cli.js} +29 -24
  32. package/dist/cli.d.ts +2 -2
  33. package/dist/cli.js +174 -92
  34. package/dist/cloud/cloud-config.d.ts +0 -1
  35. package/dist/cloud/cloud-config.js +9 -9
  36. package/dist/cloud/cloud-sync.d.ts +1 -7
  37. package/dist/cloud/cloud-sync.js +12 -12
  38. package/dist/crawl/crawl-empty.d.ts +16 -0
  39. package/dist/crawl/crawl-empty.js +24 -0
  40. package/dist/crawl/crawl-tools.js +4 -1
  41. package/dist/crawl/crawl.js +26 -7
  42. package/dist/daemon/daemon-resilience.d.ts +49 -0
  43. package/dist/daemon/daemon-resilience.js +191 -0
  44. package/dist/daemon/daemon-usefulness.d.ts +61 -0
  45. package/dist/daemon/daemon-usefulness.js +62 -0
  46. package/dist/{daemon.d.ts → daemon/daemon.d.ts} +33 -8
  47. package/dist/{daemon.js → daemon/daemon.js} +80 -48
  48. package/dist/daemon/idle-grace.d.ts +32 -0
  49. package/dist/daemon/idle-grace.js +41 -0
  50. package/dist/{idle-shutdown.d.ts → daemon/idle-shutdown.d.ts} +13 -0
  51. package/dist/{idle-shutdown.js → daemon/idle-shutdown.js} +27 -4
  52. package/dist/domain/domain-model.js +2 -2
  53. package/dist/events/body-failures.js +8 -8
  54. package/dist/events/contradictions.d.ts +1 -1
  55. package/dist/events/contradictions.js +60 -10
  56. package/dist/events/echo-mismatch.js +10 -10
  57. package/dist/events/event-filters.js +6 -6
  58. package/dist/events/json-salvage.d.ts +2 -1
  59. package/dist/events/json-salvage.js +6 -6
  60. package/dist/events/observed-in-window.d.ts +12 -0
  61. package/dist/events/observed-in-window.js +21 -0
  62. package/dist/events/predicate-eval.d.ts +43 -20
  63. package/dist/events/predicate-eval.js +159 -55
  64. package/dist/events/predicate.d.ts +2 -2
  65. package/dist/events/predicate.js +112 -35
  66. package/dist/events/reconcile.js +5 -5
  67. package/dist/events/ring-buffer.js +1 -1
  68. package/dist/events/stale-response.js +6 -6
  69. package/dist/events/testid-near-miss.d.ts +22 -0
  70. package/dist/events/testid-near-miss.js +33 -0
  71. package/dist/events/unit-mismatch.js +8 -8
  72. package/dist/flows/affected-tools.js +19 -4
  73. package/dist/flows/affected.js +1 -1
  74. package/dist/flows/annotate-target.d.ts +1 -0
  75. package/dist/flows/annotate-target.js +20 -0
  76. package/dist/flows/annotate-tools.js +25 -3
  77. package/dist/flows/annotate.js +17 -4
  78. package/dist/flows/assertion-integrity.d.ts +2 -1
  79. package/dist/flows/assertion-tiers-store.d.ts +3 -66
  80. package/dist/flows/assertion-tiers-store.js +2 -2
  81. package/dist/flows/attributed-failure.d.ts +17 -0
  82. package/dist/flows/attributed-failure.js +20 -0
  83. package/dist/flows/buddy-status.d.ts +2 -1
  84. package/dist/flows/buddy-status.js +2 -2
  85. package/dist/flows/coverage.d.ts +3 -2
  86. package/dist/flows/coverage.js +2 -2
  87. package/dist/flows/decision.js +24 -9
  88. package/dist/flows/empty-flow.d.ts +6 -0
  89. package/dist/flows/empty-flow.js +24 -0
  90. package/dist/flows/flake-store.d.ts +0 -1
  91. package/dist/flows/flake-store.js +1 -1
  92. package/dist/flows/flake.d.ts +2 -1
  93. package/dist/flows/flake.js +2 -2
  94. package/dist/flows/flow-classify.js +12 -0
  95. package/dist/flows/flow-replay-run.js +4 -4
  96. package/dist/flows/flow-replay.d.ts +5 -7
  97. package/dist/flows/flow-replay.js +114 -47
  98. package/dist/flows/flow-report.js +1 -1
  99. package/dist/flows/flow-scope.d.ts +1 -6
  100. package/dist/flows/flow-step-runners.d.ts +26 -6
  101. package/dist/flows/flow-step-runners.js +157 -6
  102. package/dist/flows/flow-success.js +20 -15
  103. package/dist/flows/flow-tools.js +53 -7
  104. package/dist/flows/flows.js +15 -11
  105. package/dist/flows/gate.d.ts +4 -3
  106. package/dist/flows/gate.js +1 -1
  107. package/dist/flows/heal-run.d.ts +0 -8
  108. package/dist/flows/heal-run.js +5 -5
  109. package/dist/flows/heal.js +3 -3
  110. package/dist/flows/predicate-to-expect.d.ts +38 -0
  111. package/dist/flows/predicate-to-expect.js +95 -0
  112. package/dist/flows/replay.d.ts +16 -1
  113. package/dist/flows/replay.js +58 -22
  114. package/dist/flows/role-anchor-nearest.d.ts +6 -0
  115. package/dist/flows/role-anchor-nearest.js +45 -0
  116. package/dist/flows/server-verify.d.ts +1 -1
  117. package/dist/flows/server-verify.js +5 -5
  118. package/dist/flows/verify-change-tools.js +32 -10
  119. package/dist/flows/verify-change-verdict.d.ts +15 -0
  120. package/dist/flows/verify-change-verdict.js +25 -0
  121. package/dist/flows/watch-batcher.d.ts +3 -2
  122. package/dist/honesty/already-true.d.ts +2 -0
  123. package/dist/honesty/already-true.js +31 -0
  124. package/dist/honesty/blind-spots.d.ts +16 -3
  125. package/dist/honesty/blind-spots.js +24 -12
  126. package/dist/honesty/honesty.d.ts +3 -2
  127. package/dist/honesty/honesty.js +4 -4
  128. package/dist/honesty/uncaptured-bodies.js +1 -1
  129. package/dist/honesty/unread-outcome.js +2 -2
  130. package/dist/honesty/verified.d.ts +22 -3
  131. package/dist/honesty/verified.js +48 -8
  132. package/dist/http-server.js +14 -7
  133. package/dist/hunt/hunt-report.d.ts +2 -1
  134. package/dist/hunt/hunt-report.js +2 -2
  135. package/dist/index.d.ts +8 -6
  136. package/dist/index.js +32 -25
  137. package/dist/init/agent-rules.d.ts +2 -1
  138. package/dist/init/agent-rules.js +45 -7
  139. package/dist/init/app-choice.d.ts +20 -0
  140. package/dist/init/app-choice.js +25 -0
  141. package/dist/init/astro-host.d.ts +21 -0
  142. package/dist/init/astro-host.js +27 -0
  143. package/dist/init/astro-patch.d.ts +16 -0
  144. package/dist/init/astro-patch.js +240 -0
  145. package/dist/init/capabilities.js +4 -1
  146. package/dist/init/cra.d.ts +37 -0
  147. package/dist/init/cra.js +90 -0
  148. package/dist/init/cursor.js +39 -4
  149. package/dist/init/desktop-doctor.d.ts +3 -2
  150. package/dist/init/desktop-doctor.js +4 -4
  151. package/dist/init/detect.d.ts +3 -2
  152. package/dist/init/detect.js +16 -5
  153. package/dist/init/mcp-registered.d.ts +12 -0
  154. package/dist/init/mcp-registered.js +14 -0
  155. package/dist/init/mcp.d.ts +27 -2
  156. package/dist/init/mcp.js +40 -4
  157. package/dist/init/next-patch.d.ts +2 -4
  158. package/dist/init/next-patch.js +109 -19
  159. package/dist/init/node-io.js +23 -6
  160. package/dist/init/plan-framework.d.ts +16 -1
  161. package/dist/init/plan-framework.js +132 -8
  162. package/dist/init/plan.d.ts +73 -8
  163. package/dist/init/plan.js +133 -34
  164. package/dist/init/project-id.d.ts +5 -9
  165. package/dist/init/project-id.js +10 -22
  166. package/dist/init/run.d.ts +5 -0
  167. package/dist/init/run.js +210 -36
  168. package/dist/init/slash-command.d.ts +9 -0
  169. package/dist/init/slash-command.js +10 -1
  170. package/dist/init/snippets.d.ts +7 -10
  171. package/dist/init/snippets.js +44 -15
  172. package/dist/init/vite-config.js +1 -1
  173. package/dist/init/workspace-apps.d.ts +23 -0
  174. package/dist/init/workspace-apps.js +68 -0
  175. package/dist/input/driven-redaction.js +1 -1
  176. package/dist/input/network-detail.js +8 -8
  177. package/dist/input/network-mock-tools.js +2 -2
  178. package/dist/input/network-mock.js +4 -4
  179. package/dist/input/real-input.js +8 -3
  180. package/dist/input/scroll-find.js +2 -2
  181. package/dist/input/scroll-tools.d.ts +0 -5
  182. package/dist/input/scroll-tools.js +11 -4
  183. package/dist/input/viewport-tools.js +2 -2
  184. package/dist/journal/ambient-store.d.ts +0 -2
  185. package/dist/journal/ambient-store.js +1 -1
  186. package/dist/journal/ambient.js +1 -1
  187. package/dist/journal/attach-journal.d.ts +2 -1
  188. package/dist/journal/deviation-report.js +6 -6
  189. package/dist/journal/deviation-service.js +1 -1
  190. package/dist/journal/envelope-store.d.ts +0 -2
  191. package/dist/journal/envelope-store.js +1 -1
  192. package/dist/journal/envelope.d.ts +2 -3
  193. package/dist/journal/envelope.js +3 -3
  194. package/dist/journal/journal-query.js +1 -1
  195. package/dist/journal/journal-recorder.d.ts +2 -1
  196. package/dist/journal/journal-recorder.js +2 -2
  197. package/dist/journal/rollups.js +9 -9
  198. package/dist/journal/session-end.d.ts +2 -1
  199. package/dist/journal/session-journal.js +4 -4
  200. package/dist/license/license.d.ts +0 -14
  201. package/dist/license/license.js +8 -8
  202. package/dist/log.d.ts +10 -0
  203. package/dist/log.js +11 -1
  204. package/dist/mcp/mcp-is-error.d.ts +13 -0
  205. package/dist/mcp/mcp-is-error.js +18 -0
  206. package/dist/mcp/mcp-outage.d.ts +31 -0
  207. package/dist/mcp/mcp-outage.js +48 -0
  208. package/dist/mcp/mcp-proxy.d.ts +124 -0
  209. package/dist/mcp/mcp-proxy.js +697 -0
  210. package/dist/{mcp.d.ts → mcp/mcp.d.ts} +13 -10
  211. package/dist/{mcp.js → mcp/mcp.js} +110 -35
  212. package/dist/mcp/proxy-handshake.d.ts +3 -0
  213. package/dist/mcp/proxy-handshake.js +54 -0
  214. package/dist/mcp/proxy-lifecycle.d.ts +64 -0
  215. package/dist/mcp/proxy-lifecycle.js +70 -0
  216. package/dist/mcp/tool-catalog-cache.d.ts +29 -0
  217. package/dist/mcp/tool-catalog-cache.js +55 -0
  218. package/dist/oracles/propose-consequences.d.ts +2 -1
  219. package/dist/oracles/propose-consequences.js +16 -11
  220. package/dist/oracles/self-instrument.d.ts +2 -1
  221. package/dist/oracles/self-instrument.js +1 -1
  222. package/dist/phenomena/phenomena.js +3 -3
  223. package/dist/platform.d.ts +16 -0
  224. package/dist/platform.js +16 -0
  225. package/dist/pool/playwright-launcher.d.ts +15 -2
  226. package/dist/pool/playwright-launcher.js +21 -2
  227. package/dist/project/fs-port.js +1 -1
  228. package/dist/project/project-tools.js +2 -2
  229. package/dist/runs/build-verification-run.js +1 -1
  230. package/dist/runs/repair-prompt.d.ts +0 -6
  231. package/dist/runs/repair-prompt.js +3 -3
  232. package/dist/runs/risk-classify.js +1 -1
  233. package/dist/runs/run-diff.d.ts +0 -2
  234. package/dist/runs/run-diff.js +3 -3
  235. package/dist/runs/run-tools.js +2 -2
  236. package/dist/runs/verification-sync.js +2 -2
  237. package/dist/runs/verify-http.js +1 -1
  238. package/dist/runs/verify-server.js +1 -1
  239. package/dist/session/command-timeout.d.ts +11 -3
  240. package/dist/session/command-timeout.js +2 -2
  241. package/dist/session/control-envelope.d.ts +6 -0
  242. package/dist/session/control-envelope.js +7 -1
  243. package/dist/session/dev-server-probe.d.ts +13 -0
  244. package/dist/session/dev-server-probe.js +52 -0
  245. package/dist/session/last-act.d.ts +17 -3
  246. package/dist/session/last-act.js +16 -4
  247. package/dist/session/live-control-tools.js +7 -2
  248. package/dist/session/live-control.js +1 -1
  249. package/dist/session/looks-like-dev-server.d.ts +14 -0
  250. package/dist/session/looks-like-dev-server.js +25 -0
  251. package/dist/session/no-session-diagnosis.d.ts +38 -0
  252. package/dist/session/no-session-diagnosis.js +70 -0
  253. package/dist/session/no-session-watch.d.ts +19 -0
  254. package/dist/session/no-session-watch.js +61 -0
  255. package/dist/session/observed-state.d.ts +4 -0
  256. package/dist/session/observed-state.js +19 -1
  257. package/dist/session/output-budget.js +1 -1
  258. package/dist/session/session-health.d.ts +8 -1
  259. package/dist/session/session-health.js +8 -7
  260. package/dist/session/session-info.d.ts +26 -7
  261. package/dist/session/session-info.js +42 -1
  262. package/dist/session/session-lease.d.ts +0 -11
  263. package/dist/session/session-lease.js +1 -1
  264. package/dist/session/session-manager.d.ts +3 -0
  265. package/dist/session/session-manager.js +52 -9
  266. package/dist/session/session-readiness.d.ts +1 -1
  267. package/dist/session/session-readiness.js +6 -1
  268. package/dist/session/session-reaper.js +1 -1
  269. package/dist/session/session-reconnect.d.ts +32 -0
  270. package/dist/session/session-reconnect.js +42 -0
  271. package/dist/session/session.d.ts +14 -2
  272. package/dist/session/session.js +69 -26
  273. package/dist/session/state-select.d.ts +1 -1
  274. package/dist/session/state-select.js +1 -1
  275. package/dist/status-payload.d.ts +19 -0
  276. package/dist/status-payload.js +11 -0
  277. package/dist/telemetry/argument-shape.js +10 -1
  278. package/dist/telemetry/browser-mode.d.ts +27 -0
  279. package/dist/telemetry/browser-mode.js +33 -0
  280. package/dist/telemetry/bug-found.d.ts +17 -21
  281. package/dist/telemetry/bug-found.js +120 -8
  282. package/dist/telemetry/cli-telemetry.d.ts +2 -12
  283. package/dist/telemetry/cli-telemetry.js +27 -4
  284. package/dist/telemetry/daemon-telemetry.d.ts +19 -0
  285. package/dist/telemetry/daemon-telemetry.js +12 -2
  286. package/dist/telemetry/dev-repo.js +4 -4
  287. package/dist/telemetry/error-fingerprint.js +21 -2
  288. package/dist/telemetry/feedback-cli.d.ts +1 -1
  289. package/dist/telemetry/feedback-cli.js +4 -4
  290. package/dist/telemetry/feedback-context.d.ts +22 -0
  291. package/dist/telemetry/feedback-context.js +41 -1
  292. package/dist/telemetry/feedback-delivery.d.ts +20 -0
  293. package/dist/telemetry/feedback-delivery.js +30 -0
  294. package/dist/telemetry/feedback-outbox.d.ts +22 -0
  295. package/dist/telemetry/feedback-outbox.js +87 -0
  296. package/dist/telemetry/feedback.d.ts +22 -1
  297. package/dist/telemetry/feedback.js +67 -8
  298. package/dist/telemetry/git-facts.js +1 -1
  299. package/dist/telemetry/session-metrics.d.ts +2 -0
  300. package/dist/telemetry/session-metrics.js +68 -6
  301. package/dist/telemetry/telemetry.d.ts +27 -2
  302. package/dist/telemetry/telemetry.js +119 -29
  303. package/dist/telemetry/verification-of.d.ts +22 -0
  304. package/dist/telemetry/verification-of.js +84 -0
  305. package/dist/tools/act-capsule.js +2 -2
  306. package/dist/tools/act-danger.d.ts +12 -0
  307. package/dist/tools/act-danger.js +20 -3
  308. package/dist/tools/act-helpers.js +4 -4
  309. package/dist/tools/act-tools.d.ts +0 -8
  310. package/dist/tools/act-tools.js +84 -115
  311. package/dist/tools/act-view.js +7 -7
  312. package/dist/tools/alias-args.d.ts +17 -0
  313. package/dist/tools/alias-args.js +25 -0
  314. package/dist/tools/assert-grade.js +9 -9
  315. package/dist/tools/assert-verdict.d.ts +3 -1
  316. package/dist/tools/assert-verdict.js +8 -5
  317. package/dist/tools/browser-tools.js +30 -11
  318. package/dist/tools/contract-tools.js +1 -1
  319. package/dist/tools/coverage-identity.d.ts +34 -0
  320. package/dist/tools/coverage-identity.js +46 -0
  321. package/dist/tools/coverage-tools.js +10 -14
  322. package/dist/tools/dynamic-tools.d.ts +2 -1
  323. package/dist/tools/dynamic-tools.js +90 -18
  324. package/dist/tools/error-recovery.d.ts +20 -2
  325. package/dist/tools/error-recovery.js +179 -4
  326. package/dist/tools/feedback-tools.d.ts +12 -1
  327. package/dist/tools/feedback-tools.js +28 -5
  328. package/dist/tools/invoke-tool.d.ts +0 -6
  329. package/dist/tools/invoke-tool.js +57 -32
  330. package/dist/tools/lease-hint.d.ts +17 -0
  331. package/dist/tools/lease-hint.js +24 -0
  332. package/dist/tools/lease-tools.js +6 -5
  333. package/dist/tools/merge-tools.d.ts +10 -1
  334. package/dist/tools/merge-tools.js +9 -3
  335. package/dist/tools/merged-name-redirect.d.ts +13 -0
  336. package/dist/tools/merged-name-redirect.js +55 -0
  337. package/dist/tools/navigate-result.d.ts +17 -0
  338. package/dist/tools/navigate-result.js +31 -0
  339. package/dist/tools/observe-tools.js +54 -20
  340. package/dist/tools/observed-nothing.d.ts +25 -0
  341. package/dist/tools/observed-nothing.js +33 -0
  342. package/dist/tools/query-paginate.js +2 -2
  343. package/dist/tools/query-shape.d.ts +18 -0
  344. package/dist/tools/query-shape.js +39 -0
  345. package/dist/tools/read-tools.js +81 -20
  346. package/dist/tools/real-input-attempt.d.ts +28 -0
  347. package/dist/tools/real-input-attempt.js +88 -0
  348. package/dist/tools/reconcile-tools.js +7 -7
  349. package/dist/tools/reload-result.d.ts +14 -0
  350. package/dist/tools/reload-result.js +29 -0
  351. package/dist/tools/snapshot-delta.d.ts +4 -5
  352. package/dist/tools/snapshot-delta.js +0 -0
  353. package/dist/tools/tool-kit.d.ts +8 -0
  354. package/dist/tools/tool-surface.d.ts +83 -0
  355. package/dist/tools/tool-surface.js +204 -0
  356. package/dist/tools/tools-helpers.js +6 -6
  357. package/dist/tools/tools.d.ts +15 -0
  358. package/dist/tools/tools.js +53 -17
  359. package/dist/tools/unadvertised-help.d.ts +5 -0
  360. package/dist/tools/unadvertised-help.js +39 -0
  361. package/dist/trace.d.ts +69 -0
  362. package/dist/trace.js +150 -0
  363. package/dist/update/nudge-credit.d.ts +4 -0
  364. package/dist/update/nudge-credit.js +53 -0
  365. package/dist/update/sdk-sync.d.ts +21 -0
  366. package/dist/update/sdk-sync.js +42 -0
  367. package/dist/update/update-checker.js +3 -3
  368. package/dist/update/update-nudge.d.ts +63 -6
  369. package/dist/update/update-nudge.js +128 -15
  370. package/dist/update/updater.d.ts +1 -9
  371. package/dist/update/updater.js +13 -8
  372. package/dist/version/peer-announce.d.ts +4 -0
  373. package/dist/version/peer-announce.js +30 -0
  374. package/dist/{server-version.js → version/server-version.js} +5 -1
  375. package/dist/version/version-nudge.d.ts +28 -0
  376. package/dist/version/version-nudge.js +40 -0
  377. package/dist/version/version-skew.d.ts +66 -0
  378. package/dist/version/version-skew.js +71 -0
  379. package/dist/visual/visual-diff.js +2 -2
  380. package/dist/visual/visual-tools.js +4 -4
  381. package/docs/agent-cheatsheet.md +85 -0
  382. package/docs/architecture.md +113 -0
  383. package/docs/benchmarks.md +255 -0
  384. package/docs/debugging.md +102 -0
  385. package/docs/deploy-checks.md +69 -0
  386. package/docs/desktop-apps.md +256 -0
  387. package/docs/enterprise.md +62 -0
  388. package/docs/fixtures.md +28 -0
  389. package/docs/flows.md +166 -0
  390. package/docs/getting-started.md +469 -0
  391. package/docs/human-control.md +63 -0
  392. package/docs/integration-patterns.md +171 -0
  393. package/docs/local-registry.md +126 -0
  394. package/docs/mint.json +61 -0
  395. package/docs/multi-agent-testing.md +55 -0
  396. package/docs/platform-integration.md +122 -0
  397. package/docs/telemetry-contract.md +214 -0
  398. package/docs/telemetry.md +184 -0
  399. package/docs/testing.md +82 -0
  400. package/docs/token-efficiency.md +80 -0
  401. package/docs/usage.md +1046 -0
  402. package/package.json +8 -5
  403. package/dist/cli-launch.js +0 -112
  404. package/dist/daemon-resilience.d.ts +0 -22
  405. package/dist/daemon-resilience.js +0 -85
  406. package/dist/mcp-proxy.d.ts +0 -67
  407. package/dist/mcp-proxy.js +0 -337
  408. package/dist/tools/profiles.d.ts +0 -37
  409. package/dist/tools/profiles.js +0 -139
  410. /package/dist/{pairing-token.d.ts → bridge/pairing-token.d.ts} +0 -0
  411. /package/dist/{token-auth.d.ts → bridge/token-auth.d.ts} +0 -0
  412. /package/dist/{token-auth.js → bridge/token-auth.js} +0 -0
  413. /package/dist/{cli-doctor.d.ts → cli/cli-doctor.d.ts} +0 -0
  414. /package/dist/{cli-verify.d.ts → cli/cli-verify.d.ts} +0 -0
  415. /package/dist/{cloud-cli.d.ts → cli/cloud-cli.d.ts} +0 -0
  416. /package/dist/{server-version.d.ts → version/server-version.d.ts} +0 -0
@@ -0,0 +1,255 @@
1
+ # How we benchmark Reticle (and why you can trust the numbers)
2
+
3
+ > This page assumes **zero** testing background. By the end you'll understand what software testing is, why AI coding agents made it urgent, how to tell a good verification tool from a bad one, and exactly how Reticle measures up against the main alternatives — including the places Reticle loses. If a term looks like jargon, it's defined the first time it appears.
4
+ >
5
+ > _The headline charts below are rendered from the measured numbers (`assets/readme/`, rendered from the measured `history.jsonl` via `assets/benchmarks/render.mjs`); supporting diagrams live in `bench/artifacts/`._
6
+
7
+ ---
8
+
9
+ ## Part 1 — The problem, from first principles
10
+
11
+ ### What is "testing"?
12
+
13
+ When you build software, **testing** is the act of checking that it actually does what it's supposed to. You click the button; does the thing happen? You submit the form; did the order get saved?
14
+
15
+ There are roughly three ways teams do this:
16
+
17
+ 1. **Manual testing** — a human clicks through the app. Accurate, but slow and easy to skip.
18
+ 2. **Automated tests** — code that clicks through the app for you. Fast to re-run, but expensive to write and notoriously **flaky** (they break for reasons unrelated to real bugs).
19
+ 3. **Nothing** — ship and hope. More common than anyone admits: surveys put ~44% of teams with no automated testing at all.
20
+
21
+ A **regression** is the specific bug this page cares about: something that _used to work_ and quietly _stopped working_ after a change. Regressions are insidious because the feature looked done — until a later edit broke it and nobody noticed.
22
+
23
+ ### Why AI agents made this urgent
24
+
25
+ AI coding agents now write a large share of new code. They're good at _producing_ code. They are bad at one specific thing: **knowing whether the code they wrote actually works.** The agent edits files, says _"done ✅"_, and moves on. It never opened the browser. So **you** become its QA department — clicking around to discover that "done" wasn't done. Developers describe being _"gaslit by coding assistants."_ This is the **"done lie."**
26
+
27
+ The honest fix is to give the agent a way to _check its own work_ — to drive the real running app and confirm the feature actually happened. That's what Reticle does. This page is about proving it does it **well**, not just that it does it.
28
+
29
+ ---
30
+
31
+ ## Part 2 — How would you even measure "good"?
32
+
33
+ Imagine three verification tools. How do you decide which is best? Two things matter, and they pull against each other:
34
+
35
+ - **Coverage** — does it actually _catch the bug_? A tool that misses regressions is useless no matter how cheap it is.
36
+ - **Cost** — how much does it make the AI _read_ to do its job? Every observation is fed into the model's limited context as **tokens** (the unit models read/write in). A tool that floods the context with thousands of tokens per look is slow, expensive, and crowds out the actual work.
37
+
38
+ A tool can cheat either axis: be cheap by looking at almost nothing (and miss bugs), or be thorough by dumping everything (and blow the budget). So the real metric has to reward **both at once**, with coverage as a hard floor.
39
+
40
+ That gives us our headline number:
41
+
42
+ > **Verification Efficiency = real regressions caught per 1,000 tokens spent looking** — and it only counts once the tool catches **100% of the bugs** with **zero false alarms** on a known-good control. (Historically abbreviated "VE"; the catch-rate floor was "RCR".)
43
+
44
+ A **false positive** (or "false alarm") is crying wolf — flagging a bug when nothing is wrong. We require zero, because a tool you can't trust when it's quiet is a tool you'll learn to ignore.
45
+
46
+ ![Verification Efficiency: catches per 1,000 tokens, gated on 100% catch rate](../bench/artifacts/chart-detection.svg)
47
+
48
+ ---
49
+
50
+ ## Part 3 — The competitors, and why these three
51
+
52
+ We compare Reticle against the two most credible agent-native browser tools, because they're what an AI agent would otherwise reach for:
53
+
54
+ - **Playwright MCP** — Microsoft's tool that lets an agent drive a browser via the accessibility tree (not screenshots). The closest "serious" alternative.
55
+ - **Chrome DevTools MCP** — Google's tool exposing Chrome's DevTools to an agent.
56
+ - **(Baseline) screenshot agents** — the common "let the model look at a picture" approach.
57
+
58
+ Why not compare to traditional test frameworks (Playwright the library, Cypress, etc.)? Because those are written and maintained by humans; they don't answer "can an _agent_ verify its own work in the loop." The three above do, so it's an apples-to-apples agent comparison.
59
+
60
+ Tool versions are pinned in `bench/raw/run-meta.json` so any run is reproducible.
61
+
62
+ ---
63
+
64
+ ## Part 4 — The three measurement passes
65
+
66
+ Different questions need different rigs. We run three (kept in the raw files as "Layer A/B/C"):
67
+
68
+ 1. **Observation-cost pass** (no AI model involved). For each bug scenario we run each tool's natural recipe and measure the exact size of what it returns — characters, bytes, and a tokenizer count. No model means no randomness: the token cost of _looking_ is measured precisely and repeatably.
69
+ 2. **Full-agent-loop pass** (a real model drives). Here an actual AI agent uses each tool end-to-end, and we record the _authoritative_ token usage the model reports. This is the real-world number; it needs an API key, so it's run periodically rather than on every change.
70
+ 3. **Replay pass** (no model). Reticle can record a flow once and _replay_ it deterministically with no AI at all. This measures the cost of re-checking a known flow — the thing a test suite does over and over, every commit.
71
+
72
+ ### The scenarios
73
+
74
+ We inject **10 realistic regressions** into a demo app plus **one no-bug control** (to catch false alarms). The bugs span the failure modes that matter — and deliberately include ones that are _invisible to a screenshot_:
75
+
76
+ | Scenario | The bug | Why it's here |
77
+ | --- | --- | --- |
78
+ | Hidden API 500 | A request silently returns a server error | A screenshot can't see a failed network call |
79
+ | Wrong status 404 | A request 404s | Same — non-visual |
80
+ | CORS blocked | A request is blocked by the browser | Non-visual |
81
+ | Silent DOM removal | A KPI card vanishes with no error | Tests "did content disappear?" |
82
+ | Route break | Navigation doesn't change the page | Common SPA bug |
83
+ | Missing modal | A dialog fails to open | Interaction regression |
84
+ | Console error, intact UI | The page looks fine but logs an error | Looks-fine-but-broken |
85
+ | Layout shift | The grid jumps / shifts | Only visible in pixels/geometry |
86
+ | Broken form validation | A form accepts bad input | Logic regression |
87
+ | Network timeout | A request hangs forever | A request that never resolves never "logs" |
88
+ | **Control (no bug)** | Nothing is wrong | Anything flagged here is a false positive |
89
+
90
+ Three of these (failed request, console error, hung request) are **categorically invisible to a screenshot** — no number of pictures will ever catch them. That's a core part of the story.
91
+
92
+ ---
93
+
94
+ ## Part 5 — The honest results, on two very different apps
95
+
96
+ We ran this two ways on purpose: a **controlled toy app** (where we can inject exact bugs and measure detection) and a **real production app** (where the numbers are messy and honest). The story holds in both — and the real app is where it gets interesting.
97
+
98
+ ![One honest test, two apps — Reticle has the highest Verification Efficiency on the controlled app and the lowest observation cost on the real dashboard](../assets/readme/bench-two-apps.png)
99
+
100
+ ### 5a — The controlled toy app (the demo)
101
+
102
+ Measured on the observation-cost pass (numbers regenerate from `bench/raw/`):
103
+
104
+ | Tool | Bugs caught (of 10) | Detection accuracy | Avg tokens per look | Verification Efficiency |
105
+ | --- | --- | --- | --- | --- |
106
+ | **Reticle** | **10 / 10** | **1.00** | **815** | **12.27** |
107
+ | Chrome DevTools MCP | 8 / 10 | 0.82 | 758 | 10.55 |
108
+ | Playwright MCP | 9 / 10 | 0.91 | 1,292 | 6.97 |
109
+
110
+ - **Reticle is the only tool that caught every regression**, with zero false alarms on the control.
111
+ - DevTools is a hair cheaper per look (758 vs 815 tokens) — **but it's cheaper because it catches less.** On the metric that combines both (Verification Efficiency), Reticle leads at 12.27 vs 10.55.
112
+ - Playwright catches a lot but is ~1.6× more expensive per look, so its efficiency is lowest here.
113
+
114
+ ### 5b — A real production app (the Reticle dashboard)
115
+
116
+ A toy app is a fair lab, but it's small. The harder, more honest test is a **real, complex app** — the [Reticle](https://reticle.sh) dashboard itself: React 19, authentication, live data, ~15 routes, a node-graph view, virtualized lists. We embedded the SDK (the Vite plugin) and drove the authenticated app with all three tools. Observing it **once** (the primary snapshot + the network log):
117
+
118
+ ![Observing the real Reticle dashboard once — Reticle 1,023 tokens vs DevTools 1,357 vs Playwright 2,193, and Reticle alone asserts success via the app's own signal](../assets/readme/bench-complex-app.png)
119
+
120
+ | Tool | Snapshot | Network | **Observe total** | Can it assert success? |
121
+ | --- | --- | --- | --- | --- |
122
+ | **Reticle** | 678 | 345 | **1,023** | ✅ via the app's own `auth:logged-in` signal — **46 tok, un-fakeable** |
123
+ | Chrome DevTools MCP | 1,105 | 252 | 1,357 | ❌ DOM/network only — can describe, can't verify intent |
124
+ | Playwright MCP | 1,522 | 671 | 2,193 | ❌ DOM/network only |
125
+
126
+ On a small page everything is cheap and the gap is modest. On a **big** page the structured read pulls ahead: Reticle is **2.1× leaner than Playwright MCP** and the cheapest overall. And only Reticle can read the app's own program state (`authenticated`, `userId`, `activeProjectId`) and assert the login _actually worked_ from a signal the app emits — the others can only look at the DOM and the network and **guess**.
127
+
128
+ ### 5c — The kicker: a real bug, caught live
129
+
130
+ Here's what makes the real-app test matter. On the **very first run, before we instrumented anything**, Reticle's network observation flagged two endpoints returning **`500`** — `GET /api/v1/projects` and `/recovery/incidents`, both failing with `column "deleted_at" does not exist` (a database migration that hadn't been applied). **The page rendered fine.** The sidebar loaded, nothing looked broken — a screenshot agent would have called it _"done."_ Reticle saw the broken backend underneath, in one look.
131
+
132
+ That is the whole thesis, demonstrated on a real app we didn't cherry-pick: **"looks done" ≠ "is done," and the difference is usually non-visual.** (We then fixed the migration; all endpoints 200.)
133
+
134
+ ### 5d — What each tool can actually do
135
+
136
+ Cost is half the story; capability is the other half. The marks below are what's **first-class and built-in** to each tool (all three are good tools — they compose: drive with theirs, assert with Reticle):
137
+
138
+ ![Capability matrix — Reticle alone asserts via the app signal, reads program state, maps DOM to source, and replays deterministically; Playwright and DevTools win on driving sites you don't own and true pixels](../assets/readme/bench-capability.png)
139
+
140
+ ### Where Reticle loses (stated plainly)
141
+
142
+ Honesty is the point of this page, so here are the places Reticle does **not** win:
143
+
144
+ - **Raw cheapness on a single trivial look:** DevTools can be a few percent cheaper per observation when it isn't catching the harder bugs. We trade those tokens for catching more.
145
+ - **True pixels:** a screenshot is the _actual rendered frame_. A bug that only shows up in real paint (a font that failed to load, a GPU/compositing glitch) can be caught by a screenshot diff and missed by Reticle's structural reads — _unless_ Reticle is explicitly asked to do a visual diff. We're honest that structure isn't pixels.
146
+ - **The full-agent-loop pass** is measured for the three tools but a screenshot-agent variant is still future work; we don't claim a head-to-head there we haven't run.
147
+
148
+ ### The part that compounds: re-running
149
+
150
+ The numbers above are for **one** verification. But a test suite's real job is the **same** check, over and over — every commit, every CI run. Here the picture changes shape:
151
+
152
+ - Reticle records a flow once, then **replays it with no AI model at all** — re-resolving each element and re-asserting the outcome — for **~175–210 tokens per run**.
153
+ - Playwright MCP and DevTools MCP have no replay: re-checking means an agent **re-drives the whole flow with the model every time**, costing tens of thousands of tokens per run.
154
+
155
+ That's a **~128–184× cost difference per re-run**, and it grows with how often you run. This is where the "much cheaper than screenshots" claim becomes dramatic rather than incremental.
156
+
157
+ ![Re-run cost: Reticle replays with no model; competitors re-drive every time](../bench/artifacts/chart-avg-tokens.svg)
158
+
159
+ ### The large-page test (where the wedge is biggest)
160
+
161
+ On a small page, structured reads and screenshots are both cheap, so the gap is modest. The advantage shows on a **big** page. On a deliberately large grid (thousands of DOM nodes):
162
+
163
+ - A **full page snapshot** costs ~**3,636 tokens**.
164
+ - A **targeted verify loop** (find one button → act → assert the success signal) costs ~**279 tokens** — and stays flat as the page grows to 5,000 rows.
165
+
166
+ That's a **13× difference**, and against a screenshot agent it's larger still: one screenshot at a normal window size is ~**1,365 image tokens** _per look_, a real loop takes several looks, and the screenshot still can't see the non-visual bugs.
167
+
168
+ ### Many agents at once (the parallel wedge)
169
+
170
+ A fleet of agents (or a parallel suite) verifying the same app doesn't need a browser each. Reticle keeps **one** headless Chromium and leases each agent an **isolated context** (separate cookies/storage/DOM). Measured on 16 flows: **35.4s** one-at-a-time vs **5.2s** across 8 leased contexts — **6.78× faster**, ~30s saved per batch, 8-way peak concurrency. The alternative — a browser per agent — costs hundreds of MB and seconds of startup each; the pool's edge grows with agent count up to its cap (`multi-agent-throughput`).
171
+
172
+ ---
173
+
174
+ ## Part 6 — Why we believe these numbers (fairness + reproducibility)
175
+
176
+ - **Every number comes from a committed harness**, not a slide. Re-run it: `pnpm bench`.
177
+ - **A no-bug control** runs in every pass, so a tool can't look good by flagging everything.
178
+ - **Tool versions are pinned**; the raw payloads are saved to `bench/raw/` so anyone can audit them.
179
+ - **The token counter is a tokenizer**, not a guess — and where we use a proxy tokenizer instead of a specific model's, we say so and lean on _relative_ differences, which are robust to the choice.
180
+ - **We publish where we lose** (above). A benchmark that only flatters its author isn't a benchmark.
181
+
182
+ ---
183
+
184
+ ## Part 7 — What this means for you
185
+
186
+ - **If you're a developer using an AI agent:** Reticle lets the agent confirm its own change actually worked — across the network call, the console, the route, the state — for a few hundred tokens, not a screenshot's thousands. "Done" starts meaning done.
187
+ - **If you run CI / a platform team:** the replay pass is the headline — deterministic re-verification with no model, so a known flow re-checks for ~200 tokens at ~0% flake, every commit.
188
+ - **If you're evaluating tools:** the axis that matters is _bugs caught per token, gated on catching them all_. Cheapness that misses regressions is a false economy.
189
+
190
+ You are now equipped to read any verification benchmark critically: ask "what's the catch rate, what's the false-positive rate, and what's the cost _per re-run_?" — and be suspicious of any vendor that won't show you where they lose.
191
+
192
+ ---
193
+
194
+ ## Part 8 — At enterprise scale (the honest "if a big company used this")
195
+
196
+ A fair question from a large engineering org (think a Datadog- or Salesforce-sized team): _does this actually pay off at our scale, or only in a demo?_ Here's the honest accounting, with every assumption stated so you can re-run it with your own numbers. **These are projections from the measured per-run costs above, not a measured enterprise deployment — labeled as such.**
197
+
198
+ ### Where it pays off (and compounds)
199
+
200
+ The win is **regression re-runs**, because that cost is paid over and over. Take a mid-size surface:
201
+
202
+ - **50 golden flows**, re-verified on **every PR**, at **200 PRs/day**.
203
+ - Reticle replays each flow **deterministically, with no model**: ~**200 tokens/flow/run** (measured).
204
+ - The agent-driven alternative re-drives each flow with an LLM: ~**30,000 tokens/flow/run** (measured Layer-C comparison).
205
+
206
+ | | Per flow / run | 50 flows × 200 PRs/day | Per year (~250 working days) |
207
+ | --- | --- | --- | --- |
208
+ | Reticle replay (no model) | ~200 tok | ~2.0 M tok/day | ~0.5 B tok/yr |
209
+ | Agent re-drive (LLM) | ~30,000 tok | ~300 M tok/day | ~75 B tok/yr |
210
+
211
+ That's a **~150× difference on the recurring axis**, and it scales linearly with flows × runs — the two numbers an enterprise has _a lot_ of. The deterministic replay also means **~0% verdict flake** (measured over repeated identical runs), which at this scale is the difference between a trusted gate and one engineers learn to ignore (recall: flaky suites get abandoned — that's the documented failure mode Reticle is built to avoid). And because replay needs no model, it has **no per-run API spend and no rate-limit ceiling** — it runs in CI like any other deterministic check.
212
+
213
+ ### Where it does NOT help (stated plainly)
214
+
215
+ An honest enterprise evaluation has to include the limits:
216
+
217
+ - **Authoring still costs model tokens.** Recording/annotating a flow the first time uses an agent. The economics only turn positive once a flow is re-run enough times to amortize that — which is exactly the enterprise case (many runs), but a flow you run twice won't pay off.
218
+ - **Tier-1 oracles need instrumentation.** The strongest, un-fakeable assertions come from app signals the team adds (a ~30-second opt-in per success event). Without them you get Tier-2 (network/route/ state) — still strong, still better than "element exists," but not the magic tier. Be realistic about the instrumentation rollout across a large codebase.
219
+ - **It is not a full replacement for an existing E2E platform on day one.** Reticle is verification in the dev/agent loop and in CI; a large org with a mature Playwright/Cypress estate adopts it alongside, starting with the agent loop and the highest-value journeys, not as a big-bang migration.
220
+ - **Structure is not pixels.** As in Part 5: a purely visual regression (a paint/font/compositing bug) needs the opt-in visual diff; the always-on structured reads won't catch it.
221
+ - **Per-project isolation is a setup step.** Multiple apps/teams on one machine each want their own bridge port (`RETICLE_PORT`) — trivial, but it's configuration a platform team should standardize.
222
+
223
+ ### The honest bottom line for a large org
224
+
225
+ Reticle is **most efficient exactly where big companies hurt most**: a large number of journeys re-verified a large number of times, where an LLM-re-drive approach's cost grows without bound and a flaky human-authored suite gets abandoned. The recurring cost drops by ~two orders of magnitude and becomes deterministic and model-free. It is **least differentiated** for one-off checks, purely visual regressions, and before the team has invested in Tier-1 signals. A sober rollout: start with the agent dev-loop, instrument the top revenue-critical journeys with success signals, wire `reticle verify` into CI for those, and expand from there.
226
+
227
+ ---
228
+
229
+ ### Appendix — the raw artifacts
230
+
231
+ - `bench/SCORECARD.md` — the one-page standing with the plain-language legend.
232
+ - `bench/METRIC.md` — the exact metric definitions.
233
+ - `bench/METHODOLOGY.md` — full design: controls, scenarios, fairness.
234
+ - `bench/history.jsonl` — every measured run over time.
235
+ - `bench/raw/` — raw payloads and per-scenario results (gitignored locally; regenerated by `pnpm bench`).
236
+
237
+ ---
238
+
239
+ ## SDK overhead — what instrumentation costs the app
240
+
241
+ An observability layer that slows the app corrupts its own performance verdicts, so Reticle holds itself to a budget: **total instrumentation overhead below 3% of main-thread time**, measured on the _hostile_ fixture — a page that never goes quiet (a ~10 messages/sec feed, a 60fps ticker, a large list), not a polite demo.
242
+
243
+ The same page is loaded in one browser under three conditions — full SDK, observers with the HUD suppressed, and Reticle absent — and Chrome's own cumulative `TaskDuration` is compared over an identical window (condition order rotated so warm-up can't favour any one of them). Three conditions, not two, so that what instrumenting costs is separable from what the HUD costs.
244
+
245
+ | | main-thread task time | busy |
246
+ | ----------------------------- | --------------------- | ------------------------------ |
247
+ | full (observers + HUD) | 1.669 s | 20.9% |
248
+ | observers only (`?nopresent`) | 1.627 s | 20.3% |
249
+ | Reticle absent (`?no-hud`) | 1.610 s | 20.1% |
250
+ | **instrumentation** | **+0.21 pp** | below the ±1.23 pp noise floor |
251
+ | **presenter HUD** | **+0.53 pp** | opt out with `present: false` |
252
+
253
+ **Result: instrumentation overhead is smaller than the method can resolve — report it as `< 1.2 percentage points`, inside the 3% budget.** The HUD is measured and reported separately, because it is a developer-visible affordance you can turn off, not a cost of observing.
254
+
255
+ Getting here required correcting the method and then fixing a real bug. The two-condition version of this bench compared the full SDK against Reticle being absent, so it charged instrumentation for the HUD too, and reported **+5.85 pp — FAIL**. Decomposing it showed almost none of that was instrumentation: a single `backdrop-filter: blur(24px)` on the HUD panel was costing **+4.03 pp** on its own — more than every observer combined — because a backdrop blur re-samples everything behind it whenever that content changes, and this fixture repaints at 60fps. Removing it took total main-thread time down 22%. Full history, including a fix that measured nothing and was reverted rather than kept, is in `bench/overhead/README.md`. Reproduce it yourself with `node bench/overhead/measure.mjs` (see `bench/overhead/README.md`, which records the ruled-out causes). causes).
@@ -0,0 +1,102 @@
1
+ # Debugging Reticle itself
2
+
3
+ > For people working **on** Reticle — and for an agent asked to explain why a flow behaved the way it did. If you are debugging **your app** with Reticle, you want [usage.md](usage.md) instead.
4
+
5
+ Reticle produces four different signals and they answer four different questions. Reaching for the wrong one is why investigations here have historically started by reading source.
6
+
7
+ | Question | Signal | Where |
8
+ | --- | --- | --- |
9
+ | What did the **agent** do to the app, and what did the app do back? | the journal | `reticle_observe` (the event window), `reticle_run_export` (a saved run), `~/.reticle/journal/` |
10
+ | What did **Reticle** do internally to answer that call? | the **trace** | daemon log, with `RETICLE_TRACE=1` |
11
+ | What happened at a milestone (daemon start, skew, refusal)? | structured log lines | daemon log |
12
+ | How much is this being used, and does it work? | telemetry | [telemetry.md](telemetry.md) |
13
+
14
+ ## The daemon log
15
+
16
+ The daemon writes newline-delimited JSON to:
17
+
18
+ ```
19
+ ~/.reticle/daemon-<port>.log # or $RETICLE_STATE_DIR/daemon-<port>.log
20
+ ```
21
+
22
+ `reticle doctor` prints the exact path for your port. Tail it while you work:
23
+
24
+ ```bash
25
+ tail -f ~/.reticle/daemon-4400.log | jq .
26
+ ```
27
+
28
+ ## Verbose flow tracing
29
+
30
+ Off by default, because a trace on every tool call is a cost on the hot path — a verification loop is 50–200 calls. Measured, so the claim is checkable: a disabled span costs **126ns** per site (against ~9ns for a bare call), which is under a microsecond per tool call and not the literal zero it is tempting to write. Turn it on **for the daemon** (the flag is read per call, but the daemon is the process doing the work, so it has to be set where the daemon starts):
31
+
32
+ ```bash
33
+ RETICLE_TRACE=1 reticle serve --port 4400
34
+ ```
35
+
36
+ Every instrumented stage then emits one line **when it ends**, carrying its own duration:
37
+
38
+ ```json
39
+ {"event":"trace","span":"browser.command","ms":412,"depth":1,"callId":"p8123-c7","ok":true,"command":"act"}
40
+ {"event":"trace","span":"tool.handler","ms":430,"depth":0,"callId":"p8123-c7","ok":true,"tool":"reticle_act"}
41
+ ```
42
+
43
+ Read it like this:
44
+
45
+ - **`callId`** groups every stage of one tool call, and is prefixed with the daemon's pid so two daemons (or one that restarted) can never claim the same id. Several agents can be inside the daemon at once, so lines interleave — the id is the only thing that makes the output a tree instead of a pile.
46
+ - **`depth`** is the nesting level. `0` is the tool handler; anything deeper ran inside it.
47
+ - **`ms`** is that stage's own wall-clock. A parent's `ms` includes its children's.
48
+ - **`ok:false`** carries an `error` field. A stage that threw is still traced — otherwise the trace would show a call that entered a stage and never left, which reads as a hang.
49
+
50
+ One line per stage, at the end, is deliberate: a start line as well would double the volume to say something the end line already implies.
51
+
52
+ ### Where the time goes
53
+
54
+ The spans that ship today:
55
+
56
+ | Span | What it covers |
57
+ | --- | --- |
58
+ | `tool.handler` | the whole tool call, at the one dispatch point both MCP and programmatic callers pass through |
59
+ | `browser.command` | one round-trip to the page |
60
+ | `flow.step` | one step of a replayed flow, with its anchor kind |
61
+ | `crawl.step` | one control the crawl clicked, including its settle budget |
62
+ | `init.plan` / `init.apply` / `init.exec` / `init.exec.retry` / `init.write` | the install, phase by phase |
63
+
64
+ The first two answer _"is this slow because of us or because of the app under test?"_ —
65
+
66
+ `browser.command` close to `tool.handler` means the app is taking the time. A large gap between them is Reticle's own overhead, and that is a performance bug of ours.
67
+
68
+ Filter to one call:
69
+
70
+ ```bash
71
+ grep '"event":"trace"' ~/.reticle/daemon-4400.log | jq -c 'select(.callId=="p8123-c7")'
72
+ ```
73
+
74
+ Or find the slowest stages across a session:
75
+
76
+ ```bash
77
+ grep '"event":"trace"' ~/.reticle/daemon-4400.log | jq -sc 'sort_by(-.ms)[:10] | .[] | {span,ms,tool}'
78
+ ```
79
+
80
+ ### The init flow
81
+
82
+ `reticle init` is synchronous end to end, so it uses `spanSync` — same line, same tree:
83
+
84
+ ```
85
+ init.plan 2ms
86
+ init.exec 133ms target=package.json command=pnpm
87
+ init.exec.retry 128ms target=package.json command=pnpm
88
+ init.write 1ms target=.reticle.json
89
+ init.apply 262ms steps=5
90
+ ```
91
+
92
+ Two things that trace makes visible and nothing else did. Planning is ~2ms, so init's wall-clock is essentially all subprocess: the package manager, and `claude mcp add` when MCP registration is on. And when the pinned install is refused, the unpinned **retry is a second full package-manager run** — init legitimately takes about twice as long on that path. Every `--local` fixture run takes it, because the version being installed is not published yet.
93
+
94
+ ### Adding a span
95
+
96
+ ```ts
97
+ import { span } from '../trace.js';
98
+
99
+ const result = await span('predicate.eval', { kind: predicate.kind }, () => evaluate(predicate));
100
+ ```
101
+
102
+ Wrap a stage worth a line in a bottleneck hunt — a session resolve, a browser round-trip, a predicate evaluation. Not every function: the trace earns its keep by being faster to read than the code, and that stops being true somewhere around one line per statement. Nesting needs no plumbing — the call id and depth ride in `AsyncLocalStorage`, so a span added five frames down still lands in the right tree without changing anyone's signature.
@@ -0,0 +1,69 @@
1
+ # Verification at the deploy choke point (Vercel / Netlify)
2
+
3
+ The strongest place to enforce verification is the moment code becomes a preview URL. Every deploy already produces one, and both Vercel and Netlify let a third party attach a **check** to it — pass/fail, shown on the PR, with no workflow file to write.
4
+
5
+ That makes the non-developer story complete: the SDK is auto-injected by the build plugin, flows are minted from toolbar recordings with auto-proposed consequences, and verification runs at publish — **without anyone writing a test.**
6
+
7
+ > Docs-only in v2.2.0. The pieces below all ship today (`reticle verify` exits 0/1 and persists a run artifact); what is _not_ built is a hosted Reticle app that registers itself as a provider. Wire it with the CI recipe until that exists.
8
+
9
+ ## The shape
10
+
11
+ ```
12
+ git push → preview deploy → Reticle verifies the preview URL → check passes/fails on the PR
13
+ ```
14
+
15
+ `reticle verify <preview-url>` is the whole integration surface:
16
+
17
+ - exits **0** when every saved flow passes, **1** otherwise — the only contract a check needs,
18
+ - prints a legible ✓/✗ report for the PR log,
19
+ - persists a `ReticleVerificationRun` artifact (`.reticle/runs/<id>.json`) so `reticle gate` and `reticle_run_export` can consume the same verdict.
20
+
21
+ ## Recipe A — CI (works today, any provider)
22
+
23
+ ```yaml
24
+ # .github/workflows/verify.yml
25
+ name: reticle
26
+ on: [deployment_status]
27
+ jobs:
28
+ verify:
29
+ if: github.event.deployment_status.state == 'success'
30
+ runs-on: ubuntu-latest
31
+ steps:
32
+ - uses: actions/checkout@v4
33
+ - uses: pnpm/action-setup@v4
34
+ - run: pnpm install --frozen-lockfile
35
+ - run: npx playwright install --with-deps chromium
36
+ # Reticle drives the preview and owns its own browser + daemon.
37
+ - run: npx reticle verify "${{ github.event.deployment_status.target_url }}" --timeout 60000
38
+ ```
39
+
40
+ The job's own pass/fail becomes the PR check. Nothing else is required.
41
+
42
+ **Non-loopback previews need pairing.** For a real preview URL (not `localhost`), Reticle injects `reticle.connect()` with a one-time token and allow-lists the preview origin — so the app does not need to be rebuilt per environment. Confirm the SDK actually runs on the deployed build: a production build that tree-shakes the dev-only SDK will connect to nothing, and `verify` will (correctly) fail with _"no app connected."_
43
+
44
+ ## Recipe B — the Checks API pattern (what a hosted Reticle would do)
45
+
46
+ Both providers expose the same shape, which is why this is one integration rather than two:
47
+
48
+ | Provider | Hook | Result surface |
49
+ | --- | --- | --- |
50
+ | Vercel | Deployment webhook → run the check → report back | Checks on the deployment / PR |
51
+ | Netlify | Deploy-succeeded webhook → run the check → report back | Deploy summary / PR |
52
+
53
+ The flow is: receive the deploy webhook → `reticle verify <target_url>` → post the verdict (and the `repair.failurePackets[]` from the run artifact) back as the check output. The artifact is stable and versioned precisely so a host platform can render it without parsing logs.
54
+
55
+ ## Pair it with the local gate
56
+
57
+ The deploy check catches what reaches a preview. `reticle gate` catches it earlier — an agent that edits a covered file cannot "finish" without re-verifying:
58
+
59
+ ```bash
60
+ reticle gate --since origin/main # exit 1 unless passing artifacts cover the affected flows
61
+ ```
62
+
63
+ Use both: `gate` in the agent's Stop hook (see `agent-cheatsheet`), `verify` at the deploy. They read the same run artifacts, so a green gate locally and a green check on the PR mean the same thing.
64
+
65
+ ## Honest limits
66
+
67
+ - **`verify` needs one connected session.** If several tabs of the app are open against the same daemon it refuses rather than guessing which to drive.
68
+ - **It replays flows sequentially against one tab**, so flows must not depend on each other's leftover state (a flow that logs in contaminates the next one). Author self-contained flows, or use `reticle_flow_verify { parallel }`, which gives each flow an isolated context.
69
+ - **No saved flows means nothing to verify** — `verify` fails rather than reporting a vacuous pass.