@reticlehq/server 3.6.0 → 3.7.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 (614) hide show
  1. package/SKILL.md +122 -123
  2. package/dist/command/cli/adhoc-suite.d.ts +14 -0
  3. package/dist/command/cli/adhoc-suite.js +42 -7
  4. package/dist/command/cli/adhoc-verdict.d.ts +18 -2
  5. package/dist/command/cli/adhoc-verdict.js +70 -6
  6. package/dist/command/cli/answers/gate-exit.d.ts +23 -0
  7. package/dist/command/cli/answers/gate-exit.js +45 -0
  8. package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
  9. package/dist/command/cli/answers/gate-hook-message.js +3 -1
  10. package/dist/command/cli/auth/device-flow.d.ts +13 -2
  11. package/dist/command/cli/auth/device-flow.js +17 -0
  12. package/dist/command/cli/cli-doctor.js +14 -0
  13. package/dist/command/cli/cli-flow-commands.d.ts +0 -11
  14. package/dist/command/cli/cli-flow-commands.js +28 -105
  15. package/dist/command/cli/cli-kill.js +3 -2
  16. package/dist/command/cli/cli-parse-grammar.d.ts +24 -0
  17. package/dist/command/cli/cli-parse-grammar.js +75 -0
  18. package/dist/command/cli/cli-parse-verify.d.ts +2 -0
  19. package/dist/command/cli/cli-parse-verify.js +18 -0
  20. package/dist/command/cli/cli-parse.d.ts +19 -28
  21. package/dist/command/cli/cli-parse.js +82 -182
  22. package/dist/command/cli/cli-update-commands.d.ts +1 -1
  23. package/dist/command/cli/cli-update-commands.js +61 -9
  24. package/dist/command/cli/cli-usage.d.ts +33 -0
  25. package/dist/command/cli/cli-usage.js +287 -0
  26. package/dist/command/cli/cli-verify.d.ts +34 -4
  27. package/dist/command/cli/cli-verify.js +81 -12
  28. package/dist/command/cli/cloud-cli.d.ts +13 -0
  29. package/dist/command/cli/cloud-cli.js +145 -333
  30. package/dist/command/cli/cloud-kit.d.ts +12 -0
  31. package/dist/command/cli/cloud-kit.js +41 -2
  32. package/dist/command/cli/cloud-link.d.ts +57 -0
  33. package/dist/command/cli/cloud-link.js +308 -0
  34. package/dist/command/cli/cloud-login.d.ts +15 -1
  35. package/dist/command/cli/cloud-login.js +67 -13
  36. package/dist/command/cli/context-command.d.ts +1 -0
  37. package/dist/command/cli/context-command.js +33 -0
  38. package/dist/command/cli/daemon-start-options.d.ts +3 -0
  39. package/dist/command/cli/daemon-start-options.js +24 -3
  40. package/dist/command/cli/doctor/doctor-coverage-line.d.ts +2 -0
  41. package/dist/command/cli/doctor/doctor-coverage-line.js +47 -0
  42. package/dist/command/cli/doctor/doctor-project-line.d.ts +0 -12
  43. package/dist/command/cli/doctor/doctor-project-line.js +5 -4
  44. package/dist/command/cli/doctor/doctor-rows.d.ts +6 -0
  45. package/dist/command/cli/doctor/doctor-rows.js +6 -0
  46. package/dist/command/cli/doctor/doctor-signing-line.d.ts +38 -0
  47. package/dist/command/cli/doctor/doctor-signing-line.js +114 -0
  48. package/dist/command/cli/known-regression.d.ts +13 -0
  49. package/dist/command/cli/known-regression.js +34 -0
  50. package/dist/command/cli/launch/sdk-version-match.d.ts +12 -0
  51. package/dist/command/cli/launch/sdk-version-match.js +25 -0
  52. package/dist/command/cli/lifecycle/daemon-lifecycle.js +11 -2
  53. package/dist/command/cli/mcp-command.d.ts +6 -0
  54. package/dist/command/cli/mcp-command.js +13 -5
  55. package/dist/command/cli/ports/port-holder.js +1 -1
  56. package/dist/command/cli/project-name.d.ts +29 -1
  57. package/dist/command/cli/project-name.js +107 -2
  58. package/dist/command/cli/setup-mcp-cli.d.ts +17 -1
  59. package/dist/command/cli/setup-mcp-cli.js +29 -8
  60. package/dist/command/cli/status/status-lines.d.ts +1 -0
  61. package/dist/command/cli/status/status-lines.js +47 -2
  62. package/dist/command/cli/status/workspace-links.d.ts +10 -0
  63. package/dist/command/cli/status/workspace-links.js +29 -0
  64. package/dist/command/cli/try-command.d.ts +96 -0
  65. package/dist/command/cli/try-command.js +362 -0
  66. package/dist/command/cli/tutorial.d.ts +0 -100
  67. package/dist/command/cli/tutorial.js +0 -178
  68. package/dist/command/cli/verify-results.d.ts +19 -0
  69. package/dist/command/cli/verify-results.js +29 -0
  70. package/dist/command/cli-onboarding.d.ts +0 -11
  71. package/dist/command/cli-onboarding.js +0 -15
  72. package/dist/command/cli.d.ts +14 -0
  73. package/dist/command/cli.js +103 -83
  74. package/dist/command/daemon/daemon-resilience.js +4 -4
  75. package/dist/command/daemon/daemon-resolve.d.ts +9 -1
  76. package/dist/command/daemon/daemon-resolve.js +49 -10
  77. package/dist/command/setup/bringup/bridge-port.d.ts +3 -1
  78. package/dist/command/setup/bringup/bridge-port.js +13 -3
  79. package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
  80. package/dist/command/setup/bringup/ensure-daemon.js +9 -2
  81. package/dist/command/setup/init/agent-restart.d.ts +23 -0
  82. package/dist/command/setup/init/agent-restart.js +28 -0
  83. package/dist/command/setup/init/init-port.d.ts +10 -1
  84. package/dist/command/setup/init/init-port.js +22 -2
  85. package/dist/command/setup/init/init-runtime.d.ts +12 -2
  86. package/dist/command/setup/init/init-runtime.js +96 -37
  87. package/dist/command/setup/node-effects.d.ts +2 -0
  88. package/dist/command/setup/node-effects.js +36 -8
  89. package/dist/command/setup/probe/existing-app.d.ts +12 -0
  90. package/dist/command/setup/probe/existing-app.js +14 -0
  91. package/dist/command/setup/remaining-steps.js +1 -1
  92. package/dist/command/setup/run-setup.d.ts +29 -9
  93. package/dist/command/setup/run-setup.js +34 -28
  94. package/dist/command/setup/setup-command.d.ts +23 -0
  95. package/dist/command/setup/setup-command.js +57 -4
  96. package/dist/command/setup/setup-mcp.js +25 -2
  97. package/dist/command/setup/tauri-signing.d.ts +19 -0
  98. package/dist/command/setup/tauri-signing.js +79 -0
  99. package/dist/command/setup/terminal/listeners.d.ts +10 -1
  100. package/dist/command/setup/terminal/listeners.js +37 -6
  101. package/dist/command/update/update-nudge.d.ts +9 -0
  102. package/dist/command/update/update-nudge.js +1 -1
  103. package/dist/command/update/updater.js +11 -15
  104. package/dist/command/version/version-nudge.js +3 -0
  105. package/dist/command/version/version-skew.d.ts +20 -1
  106. package/dist/command/version/version-skew.js +38 -2
  107. package/dist/features/crawl/crawl.js +14 -1
  108. package/dist/features/exhaust/ledger.d.ts +14 -14
  109. package/dist/features/harness/drive-report.d.ts +39 -5
  110. package/dist/features/harness/drive-report.js +271 -54
  111. package/dist/features/harness/drive-runs.d.ts +120 -0
  112. package/dist/features/harness/drive-runs.js +289 -0
  113. package/dist/features/harness/drivers.d.ts +1 -1
  114. package/dist/features/harness/drivers.js +1 -1
  115. package/dist/features/harness/explore/console-pages.d.ts +15 -0
  116. package/dist/features/harness/explore/console-pages.js +146 -0
  117. package/dist/features/harness/explore/disparity.d.ts +19 -0
  118. package/dist/features/harness/explore/disparity.js +71 -0
  119. package/dist/features/harness/explore/fake-app.d.ts +16 -0
  120. package/dist/features/harness/explore/fake-app.js +49 -0
  121. package/dist/features/harness/explore/goal-search.d.ts +26 -0
  122. package/dist/features/harness/explore/goal-search.js +144 -0
  123. package/dist/features/harness/explore/page-tree.d.ts +49 -0
  124. package/dist/features/harness/explore/page-tree.js +148 -0
  125. package/dist/features/harness/explore/site-map.d.ts +34 -0
  126. package/dist/features/harness/explore/site-map.js +150 -0
  127. package/dist/features/harness/goals.d.ts +68 -7
  128. package/dist/features/harness/goals.js +289 -36
  129. package/dist/features/harness/harness.d.ts +30 -1
  130. package/dist/features/harness/harness.js +141 -7
  131. package/dist/features/harness/platform/local-apps.d.ts +36 -3
  132. package/dist/features/harness/platform/local-apps.js +81 -5
  133. package/dist/features/harness/platform/persona-credentials.d.ts +20 -0
  134. package/dist/features/harness/platform/persona-credentials.js +69 -0
  135. package/dist/features/harness/platform/platform-drives.d.ts +61 -0
  136. package/dist/features/harness/platform/platform-drives.js +114 -0
  137. package/dist/features/harness/platform/refusal.d.ts +52 -0
  138. package/dist/features/harness/platform/refusal.js +71 -0
  139. package/dist/features/harness/platform/remote-drive.d.ts +8 -2
  140. package/dist/features/harness/platform/remote-drive.js +22 -9
  141. package/dist/features/harness/platform/script.d.ts +57 -11
  142. package/dist/features/harness/platform/script.js +144 -12
  143. package/dist/features/harness/platform/server-driver.d.ts +17 -4
  144. package/dist/features/harness/platform/server-driver.js +29 -26
  145. package/dist/features/harness/platform-config.d.ts +38 -5
  146. package/dist/features/harness/platform-config.js +93 -8
  147. package/dist/features/harness/route-guess.d.ts +13 -0
  148. package/dist/features/harness/route-guess.js +49 -0
  149. package/dist/features/harness/script/script-run.d.ts +30 -1
  150. package/dist/features/harness/script/script-run.js +355 -48
  151. package/dist/features/license/license.d.ts +2 -2
  152. package/dist/features/visual/step-shots.d.ts +31 -0
  153. package/dist/features/visual/step-shots.js +231 -0
  154. package/dist/features/visual/visual-tools.js +22 -14
  155. package/dist/hooks/client-directory.d.ts +18 -0
  156. package/dist/hooks/client-directory.js +57 -0
  157. package/dist/hooks/coding-agents.d.ts +34 -0
  158. package/dist/hooks/coding-agents.js +117 -0
  159. package/dist/hooks/driven-by.d.ts +21 -2
  160. package/dist/hooks/driven-by.js +42 -2
  161. package/dist/hooks/hook-bus.d.ts +4 -0
  162. package/dist/hooks/hook-bus.js +18 -0
  163. package/dist/index.d.ts +1 -0
  164. package/dist/index.js +26 -183
  165. package/dist/judgement/capsule/capsule-store.d.ts +2 -2
  166. package/dist/judgement/capsule/causal-summary.d.ts +15 -1
  167. package/dist/judgement/capsule/causal-summary.js +33 -0
  168. package/dist/judgement/runs/artifact/build-verification-run.d.ts +1 -1
  169. package/dist/judgement/runs/artifact/build-verification-run.js +20 -4
  170. package/dist/judgement/runs/artifact/gap-summary.d.ts +0 -18
  171. package/dist/judgement/runs/artifact/gap-summary.js +12 -3
  172. package/dist/judgement/runs/artifact/replay-mapping.js +25 -9
  173. package/dist/judgement/runs/artifact/run-store.d.ts +13 -1
  174. package/dist/judgement/runs/artifact/run-store.js +175 -8
  175. package/dist/judgement/runs/context-tools.js +59 -1
  176. package/dist/judgement/runs/default-run-id.d.ts +3 -0
  177. package/dist/judgement/runs/default-run-id.js +16 -0
  178. package/dist/judgement/runs/drive-run.d.ts +53 -5
  179. package/dist/judgement/runs/drive-run.js +234 -20
  180. package/dist/judgement/runs/resume.d.ts +44 -0
  181. package/dist/judgement/runs/resume.js +137 -0
  182. package/dist/judgement/runs/reticle-runner.js +5 -2
  183. package/dist/judgement/runs/runner-port.d.ts +5 -1
  184. package/dist/judgement/runs/runner-port.js +8 -2
  185. package/dist/judgement/runs/verification-sync.d.ts +2 -0
  186. package/dist/judgement/runs/verification-sync.js +36 -15
  187. package/dist/language/flows/decision.js +2 -1
  188. package/dist/language/flows/fields/flow-secret-field.d.ts +12 -0
  189. package/dist/language/flows/fields/flow-secret-field.js +25 -2
  190. package/dist/language/flows/flow-anchor.d.ts +7 -2
  191. package/dist/language/flows/flow-anchor.js +10 -3
  192. package/dist/language/flows/flow-intent.d.ts +1 -0
  193. package/dist/language/flows/flow-journey.d.ts +6 -0
  194. package/dist/language/flows/flow-journey.js +20 -0
  195. package/dist/language/flows/flow-learning.d.ts +4 -0
  196. package/dist/language/flows/flow-learning.js +37 -3
  197. package/dist/language/flows/flow-replay-run.js +16 -18
  198. package/dist/language/flows/flow-replay-types.d.ts +1 -1
  199. package/dist/language/flows/flow-replay.d.ts +18 -1
  200. package/dist/language/flows/flow-replay.js +22 -7
  201. package/dist/language/flows/flow-result.d.ts +22 -1
  202. package/dist/language/flows/flow-result.js +47 -2
  203. package/dist/language/flows/flow-step-runners.d.ts +2 -0
  204. package/dist/language/flows/flow-step-runners.js +12 -6
  205. package/dist/language/flows/flow-store-for-session.js +5 -1
  206. package/dist/language/flows/flow-tools.d.ts +10 -0
  207. package/dist/language/flows/flow-tools.js +61 -62
  208. package/dist/language/flows/flows.d.ts +16 -1
  209. package/dist/language/flows/flows.js +69 -10
  210. package/dist/language/flows/narrow-write.d.ts +7 -0
  211. package/dist/language/flows/narrow-write.js +36 -1
  212. package/dist/language/flows/recording/recording-backtrack.js +14 -1
  213. package/dist/language/flows/recording/tape/recordings.d.ts +29 -1
  214. package/dist/language/flows/recording/tape/recordings.js +60 -10
  215. package/dist/language/flows/replay.js +29 -6
  216. package/dist/language/flows/single-replay.d.ts +7 -0
  217. package/dist/language/flows/single-replay.js +26 -0
  218. package/dist/language/flows/verify-change-tools.d.ts +1 -0
  219. package/dist/language/flows/verify-change-tools.js +200 -193
  220. package/dist/memory/cloud/cloud-config.d.ts +10 -1
  221. package/dist/memory/cloud/cloud-config.js +19 -5
  222. package/dist/memory/cloud/cloud-sync.js +3 -3
  223. package/dist/memory/cloud/harness-config.d.ts +49 -0
  224. package/dist/memory/cloud/harness-config.js +16 -20
  225. package/dist/memory/cloud/memory-scope.d.ts +17 -0
  226. package/dist/memory/cloud/memory-scope.js +22 -0
  227. package/dist/memory/cloud/sync-cycle.d.ts +32 -4
  228. package/dist/memory/cloud/sync-cycle.js +113 -12
  229. package/dist/memory/cloud/sync-daemon.d.ts +11 -0
  230. package/dist/memory/cloud/sync-daemon.js +114 -4
  231. package/dist/memory/cloud/sync-disk.js +26 -2
  232. package/dist/memory/cloud/sync-screenshots.d.ts +32 -0
  233. package/dist/memory/cloud/sync-screenshots.js +105 -0
  234. package/dist/memory/cloud/unsynced-roots.d.ts +47 -0
  235. package/dist/memory/cloud/unsynced-roots.js +166 -0
  236. package/dist/memory/impact/account-watch.d.ts +16 -1
  237. package/dist/memory/impact/account-watch.js +26 -1
  238. package/dist/memory/impact/impact-store.d.ts +1 -4
  239. package/dist/memory/impact/impact-store.js +32 -42
  240. package/dist/memory/intent/inline-intent.d.ts +1 -0
  241. package/dist/memory/intent/intent-shard-store.js +16 -4
  242. package/dist/memory/intent/intent-shard.d.ts +12 -0
  243. package/dist/memory/intent/intent-store.d.ts +1 -0
  244. package/dist/memory/intent/intent-tools.js +42 -2
  245. package/dist/memory/intent/open-intents.d.ts +6 -0
  246. package/dist/memory/intent/open-intents.js +10 -1
  247. package/dist/memory/intent/settled-words.d.ts +24 -0
  248. package/dist/memory/intent/settled-words.js +130 -0
  249. package/dist/memory/journal/drive-flow.d.ts +16 -0
  250. package/dist/memory/journal/drive-flow.js +34 -2
  251. package/dist/memory/journal/drive-run-flush.d.ts +2 -0
  252. package/dist/memory/journal/drive-run-flush.js +20 -5
  253. package/dist/memory/journal/journal-recorder.js +46 -3
  254. package/dist/memory/journal/on-disk/retention.d.ts +5 -0
  255. package/dist/memory/journal/on-disk/retention.js +27 -2
  256. package/dist/memory/journal/on-disk/workspace-tiers.js +2 -0
  257. package/dist/memory/journal/session-end.d.ts +15 -1
  258. package/dist/memory/journal/session-end.js +38 -7
  259. package/dist/memory/project/artifact-root-resolver.js +33 -5
  260. package/dist/memory/project/artifact-root.d.ts +4 -3
  261. package/dist/memory/project/artifact-root.js +2 -2
  262. package/dist/memory/project/dir/reticle-dir.d.ts +14 -0
  263. package/dist/memory/project/dir/reticle-dir.js +23 -2
  264. package/dist/memory/project/link-directory.d.ts +15 -0
  265. package/dist/memory/project/link-directory.js +44 -0
  266. package/dist/memory/project/root-claims.d.ts +6 -0
  267. package/dist/memory/project/root-claims.js +39 -0
  268. package/dist/memory/project/session-root.d.ts +2 -0
  269. package/dist/memory/project/session-root.js +9 -1
  270. package/dist/memory/project/sync-status.d.ts +46 -0
  271. package/dist/memory/project/sync-status.js +135 -1
  272. package/dist/memory/recall/memory-tools.js +46 -3
  273. package/dist/memory/recall/platform-memory.d.ts +34 -0
  274. package/dist/memory/recall/platform-memory.js +139 -0
  275. package/dist/memory/recall/project-memory.js +36 -8
  276. package/dist/portal/bridge/bridge.d.ts +9 -5
  277. package/dist/portal/bridge/bridge.js +66 -23
  278. package/dist/portal/bridge/harness-request.d.ts +23 -0
  279. package/dist/portal/bridge/harness-request.js +27 -0
  280. package/dist/portal/bridge/wrong-path.d.ts +17 -0
  281. package/dist/portal/bridge/wrong-path.js +35 -0
  282. package/dist/portal/input/network-mock-tools.js +11 -2
  283. package/dist/portal/input/real-input.d.ts +2 -0
  284. package/dist/portal/input/real-input.js +13 -10
  285. package/dist/portal/pool/browser-pool.d.ts +48 -0
  286. package/dist/portal/pool/browser-pool.js +120 -2
  287. package/dist/portal/pool/context-permissions.d.ts +33 -0
  288. package/dist/portal/pool/context-permissions.js +33 -0
  289. package/dist/portal/pool/lease-marker-stamp.d.ts +23 -0
  290. package/dist/portal/pool/lease-marker-stamp.js +49 -0
  291. package/dist/portal/pool/playwright-launcher.d.ts +27 -5
  292. package/dist/portal/pool/playwright-launcher.js +59 -14
  293. package/dist/portal/pool/pool-contract.d.ts +21 -1
  294. package/dist/portal/session/agent-link.d.ts +8 -0
  295. package/dist/portal/session/agent-link.js +17 -0
  296. package/dist/portal/session/command-payload.js +6 -1
  297. package/dist/portal/session/daemon-answers.d.ts +3 -3
  298. package/dist/portal/session/daemon-answers.js +4 -2
  299. package/dist/portal/session/dev-server/dev-command.d.ts +9 -0
  300. package/dist/portal/session/dev-server/dev-command.js +27 -1
  301. package/dist/portal/session/facts/observed-state.d.ts +16 -18
  302. package/dist/portal/session/facts/observed-state.js +46 -3
  303. package/dist/portal/session/human/live-control.d.ts +9 -2
  304. package/dist/portal/session/human/live-control.js +12 -3
  305. package/dist/portal/session/live-control-tools.js +82 -13
  306. package/dist/portal/session/narration-args.d.ts +5 -0
  307. package/dist/portal/session/narration-args.js +17 -0
  308. package/dist/portal/session/no-session-diagnosis.d.ts +1 -1
  309. package/dist/portal/session/no-session-diagnosis.js +31 -9
  310. package/dist/portal/session/no-session-next-action.d.ts +20 -0
  311. package/dist/portal/session/no-session-next-action.js +134 -61
  312. package/dist/portal/session/no-session-watch.js +179 -22
  313. package/dist/portal/session/presence/session-lease.js +1 -1
  314. package/dist/portal/session/recorded-gaps.d.ts +97 -0
  315. package/dist/portal/session/recorded-gaps.js +251 -0
  316. package/dist/portal/session/session-health.d.ts +11 -0
  317. package/dist/portal/session/session-health.js +3 -1
  318. package/dist/portal/session/session-info.js +2 -1
  319. package/dist/portal/session/session-manager.d.ts +18 -0
  320. package/dist/portal/session/session-manager.js +54 -3
  321. package/dist/portal/session/session-successor.d.ts +8 -0
  322. package/dist/portal/session/session-successor.js +1 -1
  323. package/dist/portal/session/session.d.ts +15 -28
  324. package/dist/portal/session/session.js +60 -61
  325. package/dist/portal/session/timing/command-timeout.js +25 -1
  326. package/dist/portal/session/timing/wall-clock.d.ts +1 -1
  327. package/dist/portal/session/timing/wall-clock.js +1 -1
  328. package/dist/portal/session/zero-install-first-call.d.ts +31 -0
  329. package/dist/portal/session/zero-install-first-call.js +88 -0
  330. package/dist/start-options.d.ts +7 -1
  331. package/dist/start-wiring.d.ts +63 -0
  332. package/dist/start-wiring.js +169 -0
  333. package/dist/status-payload.d.ts +13 -1
  334. package/dist/status-payload.js +13 -1
  335. package/dist/surface/http-server.js +7 -1
  336. package/dist/surface/mcp/attach-memory.d.ts +1 -0
  337. package/dist/surface/mcp/attach-memory.js +12 -1
  338. package/dist/surface/mcp/mcp-proxy.d.ts +4 -0
  339. package/dist/surface/mcp/mcp-proxy.js +29 -8
  340. package/dist/surface/mcp/mcp.d.ts +23 -0
  341. package/dist/surface/mcp/mcp.js +34 -4
  342. package/dist/surface/mcp/proxy/drive-calls.d.ts +10 -0
  343. package/dist/surface/mcp/proxy/drive-calls.js +27 -0
  344. package/dist/surface/mcp/proxy/mcp-post-transport.js +5 -0
  345. package/dist/surface/mcp/server-instructions.js +22 -14
  346. package/dist/surface/mcp/shared-params.js +1 -1
  347. package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
  348. package/dist/surface/mcp/surface-vocabulary.js +1 -0
  349. package/dist/surface/tools/account-tool.d.ts +22 -0
  350. package/dist/surface/tools/account-tool.js +157 -0
  351. package/dist/surface/tools/act/act-danger.d.ts +11 -0
  352. package/dist/surface/tools/act/act-danger.js +38 -1
  353. package/dist/surface/tools/act/act-observation.d.ts +33 -0
  354. package/dist/surface/tools/act/act-observation.js +57 -0
  355. package/dist/surface/tools/act/act-preflight.js +25 -2
  356. package/dist/surface/tools/act/act-target.js +8 -3
  357. package/dist/surface/tools/act/resolve-target.d.ts +1 -1
  358. package/dist/surface/tools/act/resolve-target.js +18 -3
  359. package/dist/surface/tools/act/screen-request.d.ts +34 -0
  360. package/dist/surface/tools/act/screen-request.js +113 -0
  361. package/dist/surface/tools/act/sequence-grade.d.ts +8 -0
  362. package/dist/surface/tools/act/sequence-grade.js +13 -2
  363. package/dist/surface/tools/act-sequence-tool.js +136 -27
  364. package/dist/surface/tools/act-tools.d.ts +0 -9
  365. package/dist/surface/tools/act-tools.js +48 -34
  366. package/dist/surface/tools/agent/app-notes-learning.d.ts +7 -0
  367. package/dist/surface/tools/agent/app-notes-learning.js +80 -0
  368. package/dist/surface/tools/agent/app-notes.d.ts +4 -0
  369. package/dist/surface/tools/agent/app-notes.js +48 -0
  370. package/dist/surface/tools/agent/build-staleness.d.ts +7 -0
  371. package/dist/surface/tools/agent/build-staleness.js +62 -0
  372. package/dist/surface/tools/agent/compact-envelope.d.ts +80 -0
  373. package/dist/surface/tools/agent/compact-envelope.js +374 -0
  374. package/dist/surface/tools/agent/for-the-agent.d.ts +12 -0
  375. package/dist/surface/tools/agent/for-the-agent.js +44 -0
  376. package/dist/surface/tools/agent/notices.d.ts +50 -0
  377. package/dist/surface/tools/agent/notices.js +152 -0
  378. package/dist/surface/tools/agent/reteach.d.ts +11 -0
  379. package/dist/surface/tools/agent/reteach.js +50 -0
  380. package/dist/surface/tools/args/alias-args.d.ts +5 -0
  381. package/dist/surface/tools/args/alias-args.js +10 -0
  382. package/dist/surface/tools/args/confirm-dangerous-arg.d.ts +6 -0
  383. package/dist/surface/tools/args/confirm-dangerous-arg.js +6 -0
  384. package/dist/surface/tools/assert/assert-source.d.ts +15 -0
  385. package/dist/surface/tools/assert/assert-source.js +40 -0
  386. package/dist/surface/tools/assert/assert-verdict.js +25 -15
  387. package/dist/surface/tools/browser-tools.js +43 -1
  388. package/dist/surface/tools/chat-drives.d.ts +75 -0
  389. package/dist/surface/tools/chat-drives.js +265 -21
  390. package/dist/surface/tools/coverage-tools.d.ts +2 -10
  391. package/dist/surface/tools/coverage-tools.js +2 -53
  392. package/dist/surface/tools/dynamic-tools.js +29 -1
  393. package/dist/surface/tools/empty-session-list.d.ts +10 -0
  394. package/dist/surface/tools/empty-session-list.js +45 -5
  395. package/dist/surface/tools/error-recovery.d.ts +8 -0
  396. package/dist/surface/tools/error-recovery.js +69 -5
  397. package/dist/surface/tools/explore-tools.d.ts +23 -2
  398. package/dist/surface/tools/explore-tools.js +377 -74
  399. package/dist/surface/tools/feedback-tools.d.ts +2 -3
  400. package/dist/surface/tools/feedback-tools.js +4 -3
  401. package/dist/surface/tools/gap-novelty.d.ts +3 -1
  402. package/dist/surface/tools/gap-novelty.js +8 -1
  403. package/dist/surface/tools/harness-explore.d.ts +52 -73
  404. package/dist/surface/tools/harness-explore.js +177 -146
  405. package/dist/surface/tools/harness-gate.d.ts +88 -0
  406. package/dist/surface/tools/harness-gate.js +235 -0
  407. package/dist/surface/tools/harness-hunt.d.ts +43 -0
  408. package/dist/surface/tools/harness-hunt.js +215 -0
  409. package/dist/surface/tools/harness-plan.d.ts +5 -0
  410. package/dist/surface/tools/harness-plan.js +7 -0
  411. package/dist/surface/tools/harness-script.d.ts +22 -0
  412. package/dist/surface/tools/harness-script.js +256 -38
  413. package/dist/surface/tools/harness-tab-guard.d.ts +5 -0
  414. package/dist/surface/tools/harness-tab-guard.js +27 -0
  415. package/dist/surface/tools/harness-toolset.d.ts +8 -0
  416. package/dist/surface/tools/harness-toolset.js +27 -4
  417. package/dist/surface/tools/human-notes.d.ts +16 -0
  418. package/dist/surface/tools/human-notes.js +27 -0
  419. package/dist/surface/tools/invoke-tool.d.ts +5 -2
  420. package/dist/surface/tools/invoke-tool.js +220 -93
  421. package/dist/surface/tools/lease-hint.js +26 -5
  422. package/dist/surface/tools/lease-permissions.d.ts +33 -0
  423. package/dist/surface/tools/lease-permissions.js +73 -0
  424. package/dist/surface/tools/lease-readiness.d.ts +38 -0
  425. package/dist/surface/tools/lease-readiness.js +57 -0
  426. package/dist/surface/tools/lease-seed.d.ts +20 -0
  427. package/dist/surface/tools/lease-seed.js +45 -1
  428. package/dist/surface/tools/lease-tools.d.ts +10 -1
  429. package/dist/surface/tools/lease-tools.js +119 -69
  430. package/dist/surface/tools/live-call-text.js +2 -2
  431. package/dist/surface/tools/merge-tools.js +42 -2
  432. package/dist/surface/tools/merged-name-redirect.js +4 -0
  433. package/dist/surface/tools/next-step.d.ts +11 -1
  434. package/dist/surface/tools/next-step.js +73 -18
  435. package/dist/surface/tools/observe-tools.js +43 -5
  436. package/dist/surface/tools/platform-moment.d.ts +60 -0
  437. package/dist/surface/tools/platform-moment.js +132 -4
  438. package/dist/surface/tools/read-tools.js +65 -14
  439. package/dist/surface/tools/reticle-result.d.ts +120 -0
  440. package/dist/surface/tools/reticle-result.js +364 -0
  441. package/dist/surface/tools/tool-kit.d.ts +68 -2
  442. package/dist/surface/tools/tool-kit.js +73 -1
  443. package/dist/surface/tools/tools.js +25 -13
  444. package/dist/telemetry/account-envelope.d.ts +7 -0
  445. package/dist/telemetry/account-envelope.js +61 -0
  446. package/dist/telemetry/agent-client.d.ts +15 -0
  447. package/dist/telemetry/agent-client.js +57 -0
  448. package/dist/telemetry/app-instrumented.js +9 -2
  449. package/dist/telemetry/argument-shape.d.ts +7 -0
  450. package/dist/telemetry/argument-shape.js +86 -1
  451. package/dist/telemetry/automation-hint.d.ts +2 -3
  452. package/dist/telemetry/automation-hint.js +33 -8
  453. package/dist/telemetry/cli-telemetry.js +7 -2
  454. package/dist/telemetry/daemon-telemetry.js +3 -0
  455. package/dist/telemetry/error-fingerprint.d.ts +10 -1
  456. package/dist/telemetry/error-fingerprint.js +61 -5
  457. package/dist/telemetry/feedback-cli.d.ts +0 -13
  458. package/dist/telemetry/feedback-cli.js +0 -77
  459. package/dist/telemetry/feedback.d.ts +13 -0
  460. package/dist/telemetry/feedback.js +183 -17
  461. package/dist/telemetry/harness-run.d.ts +18 -0
  462. package/dist/telemetry/harness-run.js +80 -0
  463. package/dist/telemetry/hud-events.d.ts +16 -0
  464. package/dist/telemetry/hud-events.js +27 -0
  465. package/dist/telemetry/hud-metrics.d.ts +27 -6
  466. package/dist/telemetry/hud-metrics.js +99 -25
  467. package/dist/telemetry/init-telemetry.js +2 -2
  468. package/dist/telemetry/install-source.d.ts +13 -25
  469. package/dist/telemetry/install-source.js +44 -3
  470. package/dist/telemetry/mcp-connection.d.ts +0 -14
  471. package/dist/telemetry/mcp-connection.js +5 -1
  472. package/dist/telemetry/onboarding-firsts.d.ts +32 -0
  473. package/dist/telemetry/onboarding-firsts.js +81 -6
  474. package/dist/telemetry/platform-linked.d.ts +5 -0
  475. package/dist/telemetry/platform-linked.js +32 -0
  476. package/dist/telemetry/project-profile.js +5 -3
  477. package/dist/telemetry/proxy-telemetry.js +4 -1
  478. package/dist/telemetry/session-metrics.d.ts +15 -4
  479. package/dist/telemetry/session-metrics.js +88 -52
  480. package/dist/telemetry/telemetry.d.ts +26 -2
  481. package/dist/telemetry/telemetry.js +102 -21
  482. package/dist/telemetry/verification-of.d.ts +3 -1
  483. package/dist/telemetry/verification-of.js +12 -4
  484. package/dist/wire-journal.d.ts +2 -2
  485. package/dist/wire-journal.js +16 -5
  486. package/docs/README.md +2 -2
  487. package/docs/actions.mdx +6 -3
  488. package/docs/adapters.md +1 -1
  489. package/docs/agent-cheatsheet.md +24 -27
  490. package/docs/architecture.md +5 -5
  491. package/docs/autodrive.md +13 -12
  492. package/docs/benchmarks.md +5 -5
  493. package/docs/best-practices.mdx +27 -9
  494. package/docs/capabilities.mdx +14 -16
  495. package/docs/cli/affected.mdx +1 -1
  496. package/docs/cli/cloud.mdx +54 -75
  497. package/docs/cli/doctor.mdx +8 -3
  498. package/docs/cli/drive.mdx +12 -12
  499. package/docs/cli/feedback.mdx +3 -3
  500. package/docs/cli/gate.mdx +7 -2
  501. package/docs/cli/help.mdx +50 -55
  502. package/docs/cli/init.mdx +32 -15
  503. package/docs/cli/license.mdx +12 -8
  504. package/docs/cli/mcp.mdx +4 -4
  505. package/docs/cli/open.mdx +3 -3
  506. package/docs/cli/report.mdx +4 -2
  507. package/docs/cli/restart.mdx +2 -2
  508. package/docs/cli/rollback.mdx +14 -8
  509. package/docs/cli/serve.mdx +4 -4
  510. package/docs/cli/setup.mdx +23 -0
  511. package/docs/cli/status.mdx +13 -4
  512. package/docs/cli/stop.mdx +67 -8
  513. package/docs/cli/try.mdx +62 -0
  514. package/docs/cli/update.mdx +4 -3
  515. package/docs/cli/verify.mdx +17 -6
  516. package/docs/cli/version.mdx +3 -2
  517. package/docs/cli.mdx +110 -41
  518. package/docs/debugging.md +3 -3
  519. package/docs/deploy-checks.md +1 -1
  520. package/docs/desktop.mdx +5 -3
  521. package/docs/enterprise.md +11 -10
  522. package/docs/environment.mdx +5 -2
  523. package/docs/faq.mdx +3 -3
  524. package/docs/first-drive.md +5 -4
  525. package/docs/flows.md +35 -27
  526. package/docs/for-agents.md +4 -5
  527. package/docs/frameworks.mdx +32 -21
  528. package/docs/getting-started.md +66 -64
  529. package/docs/human-control.md +15 -14
  530. package/docs/index.mdx +15 -43
  531. package/docs/install-agentic.mdx +22 -37
  532. package/docs/install-manual.mdx +22 -12
  533. package/docs/instrumentation.mdx +5 -3
  534. package/docs/integration-patterns.md +7 -7
  535. package/docs/license-activation.mdx +1 -1
  536. package/docs/multi-agent-testing.md +24 -6
  537. package/docs/packages/babel-plugin.mdx +4 -2
  538. package/docs/packages/browser.mdx +16 -10
  539. package/docs/packages/core.mdx +12 -5
  540. package/docs/packages/electron.mdx +3 -2
  541. package/docs/packages/engine.mdx +1 -1
  542. package/docs/packages/eslint-plugin.mdx +18 -12
  543. package/docs/packages/next.mdx +8 -7
  544. package/docs/packages/open-verification.mdx +1 -1
  545. package/docs/packages/server.mdx +5 -5
  546. package/docs/packages/tauri.mdx +8 -8
  547. package/docs/packages/test.mdx +4 -10
  548. package/docs/packages/vite-plugin.mdx +11 -4
  549. package/docs/packages.mdx +11 -15
  550. package/docs/platform-integration.md +6 -5
  551. package/docs/predicates.mdx +40 -24
  552. package/docs/quickstart.mdx +58 -29
  553. package/docs/required-checks.md +8 -7
  554. package/docs/reticle-manual.md +15 -5
  555. package/docs/skill-file.mdx +17 -79
  556. package/docs/skill-setup.md +9 -9
  557. package/docs/skill.md +200 -0
  558. package/docs/system-map.md +7 -7
  559. package/docs/telemetry.md +22 -24
  560. package/docs/testing.md +4 -4
  561. package/docs/token-efficiency.md +12 -12
  562. package/docs/tools/act-and-wait.mdx +9 -2
  563. package/docs/tools/act-sequence.mdx +6 -7
  564. package/docs/tools/act.mdx +2 -2
  565. package/docs/tools/assert.mdx +18 -17
  566. package/docs/tools/console.mdx +9 -9
  567. package/docs/tools/inspect.mdx +16 -7
  568. package/docs/tools/look.mdx +24 -0
  569. package/docs/tools/navigate.mdx +5 -3
  570. package/docs/tools/network.mdx +2 -2
  571. package/docs/tools/observe.mdx +6 -6
  572. package/docs/tools/overview.mdx +34 -33
  573. package/docs/tools/query.mdx +5 -5
  574. package/docs/tools/session-and-feedback.mdx +13 -4
  575. package/docs/tools/sessions.mdx +8 -8
  576. package/docs/tools/snapshot.mdx +6 -5
  577. package/docs/tools/state.mdx +9 -9
  578. package/docs/tools/tools-and-run.mdx +26 -24
  579. package/docs/tools/verify.mdx +28 -0
  580. package/docs/tools/wait-for.mdx +8 -4
  581. package/docs/troubleshooting.mdx +21 -6
  582. package/docs/usage.md +51 -45
  583. package/docs/use-cases.mdx +3 -3
  584. package/docs/vs-chrome-devtools-mcp.mdx +9 -6
  585. package/docs/vs-playwright-mcp.mdx +3 -1
  586. package/docs/what-is-recorded.md +7 -5
  587. package/docs/what-is-reticle.mdx +2 -2
  588. package/docs/why-reticle.mdx +1 -1
  589. package/package.json +6 -5
  590. package/dist/command/cli/demo/demo-page.d.ts +0 -78
  591. package/dist/command/cli/demo/demo-page.js +0 -249
  592. package/dist/command/cli/demo/demo-run.d.ts +0 -38
  593. package/dist/command/cli/demo/demo-run.js +0 -138
  594. package/dist/judgement/hunt/hunt-report.d.ts +0 -49
  595. package/dist/judgement/hunt/hunt-report.js +0 -84
  596. package/dist/language/flows/buddy-status.d.ts +0 -25
  597. package/dist/language/flows/buddy-status.js +0 -32
  598. package/dist/language/flows/change/watch-batcher.d.ts +0 -18
  599. package/dist/language/flows/change/watch-batcher.js +0 -19
  600. package/dist/memory/cloud/harness-offer.d.ts +0 -44
  601. package/dist/memory/cloud/harness-offer.js +0 -145
  602. package/dist/surface/tools/feature-capture.d.ts +0 -151
  603. package/dist/surface/tools/feature-capture.js +0 -235
  604. package/dist/surface/tools/tool-hit-rate.d.ts +0 -87
  605. package/dist/surface/tools/tool-hit-rate.js +0 -90
  606. package/dist/telemetry/harness-drive.d.ts +0 -4
  607. package/dist/telemetry/harness-drive.js +0 -35
  608. package/dist/telemetry/identify.d.ts +0 -22
  609. package/dist/telemetry/identify.js +0 -73
  610. package/docs/cli/capsules.mdx +0 -70
  611. package/docs/cli/hunt.mdx +0 -73
  612. package/docs/cli/identify.mdx +0 -76
  613. package/docs/cli/kill.mdx +0 -91
  614. package/docs/cli/watch.mdx +0 -62
package/dist/index.d.ts CHANGED
@@ -75,6 +75,7 @@ export interface RunningServer {
75
75
  close: () => Promise<void>;
76
76
  }
77
77
  export { resolveBridgeSecurity } from './portal/bridge/bridge-security.js';
78
+ /** Start the Reticle bridge (browser WS endpoint) and, by default, the MCP stdio server. */
78
79
  export declare function start(options?: StartOptions): Promise<RunningServer>;
79
80
  /**
80
81
  * Start the Reticle bridge in daemon mode: a single HTTP server handles both the WebSocket
package/dist/index.js CHANGED
@@ -1,29 +1,25 @@
1
1
  import { applyHarnessSwitch, harnessConfigsByRoot } from './memory/cloud/harness-config.js';
2
2
  import { coveragePercents } from './features/exhaust/ledger.js';
3
- import { firstRunWiring } from './portal/session/first-run-wiring.js';
4
- import { fetchPlatformConfig } from './features/harness/platform-config.js';
5
- import { watchAccountFiles } from './memory/impact/account-watch.js';
3
+ import { agentWiring } from './portal/session/zero-install-first-call.js';
4
+ import { pushIfMoved, watchAccountFiles } from './memory/impact/account-watch.js';
6
5
  import { SESSION_FILE } from './command/cli/cloud-kit.js';
7
6
  import { join } from 'node:path';
8
7
  import { homedir } from 'node:os';
9
- import { linkedCloudPort, platformEnvPort, sessionCloudPort } from './memory/cloud/cloud-config.js';
8
+ import { linkedCloudPort, sessionCloudPort } from './memory/cloud/cloud-config.js';
10
9
  import { sessionRoot } from './memory/project/session-root.js';
11
10
  import { attachCloudSync } from './memory/cloud/sync-daemon.js';
12
11
  import { wireHooks } from './hooks/hook-commands.js';
13
12
  import { currentDrivenBy } from './hooks/driven-by.js';
14
- import { artifactRootResolver, knownProjectCandidates, projectDirectoryFor, } from './memory/project/artifact-root-resolver.js';
13
+ import { artifactRootResolver } from './memory/project/artifact-root-resolver.js';
15
14
  import { servingDirectoryOf } from './portal/session/serving-directory.js';
16
15
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
17
- import { AGENT_STOPPED_NOTICE, RETICLE_DEFAULT_PORT, bridgeWsUrl, ReticleCommand, ReticleDir, ReticleEnv, LOOPBACK_HOST, EventType, } from '@reticlehq/core';
18
- import { originOf } from './portal/session/session-manager.js';
19
- import { setBrowserMode, BrowserMode } from './telemetry/browser-mode.js';
16
+ import { AGENT_STOPPED_NOTICE, RETICLE_DEFAULT_PORT, ReticleCommand, ReticleDir, ReticleEnv, LOOPBACK_HOST, } from '@reticlehq/core';
20
17
  import { replayFromHud } from './language/flows/replay-from-hud.js';
21
18
  import { createSharedServer } from './surface/http-server.js';
22
19
  import { openLoopbackAlias } from './command/daemon/binding/loopback-alias.js';
23
20
  import { reportAppInstrumented } from './telemetry/app-instrumented.js';
24
21
  import { resolveBridgeSecurityWithAutoToken } from './portal/bridge/bridge-security.js';
25
22
  import { Bridge } from './portal/bridge/bridge.js';
26
- import { sdkFixForDirectory } from './command/version/sdk-fix.js';
27
23
  import { connectionSkew } from './command/version/version-nudge.js';
28
24
  import { SERVER_VERSION } from './command/version/identity/server-version.js';
29
25
  import { BaselineStore } from './memory/project/baselines.js';
@@ -45,27 +41,22 @@ import { startVerifyServer } from './judgement/runs/verify-server.js';
45
41
  import { createMcpServer } from './surface/mcp/mcp.js';
46
42
  import { instructionStateAt } from './surface/mcp/mcp-proxy.js';
47
43
  import { LEASE_ACQUIRE_TOOL } from './surface/tools/lease-tools.js';
48
- import { startChatDrives } from './surface/tools/chat-drives.js';
44
+ import { attachHudHarness, projectLinkOnly, startChatDrives } from './surface/tools/chat-drives.js';
49
45
  import { runTool } from './surface/tools/invoke-tool.js';
50
46
  import { SessionReaper, endAllSessions, MCP_DISCONNECT_SUMMARY, } from './portal/session/session-reaper.js';
51
47
  import { wireSessionScope } from './portal/session/no-session-watch.js';
52
48
  import { buildIdlePredicate, noteSetupHold } from './command/daemon/lifetime/daemon-usefulness.js';
53
49
  import { resolveToolSurface } from './surface/tools/tool-surface.js';
54
50
  import { statusPayload } from './status-payload.js';
55
- import { CdpRealInputProvider, LaunchedRealInputProvider } from './portal/input/real-input.js';
56
- import { cpus } from 'node:os';
57
- import { BrowserPool } from './portal/pool/browser-pool.js';
58
51
  import { AGENT_ALREADY_DRIVING_ELSEWHERE, shouldGreetWithLeaseNotice, } from './portal/session/lease-visibility.js';
59
- import { playwrightLauncher, resolveMaxContexts } from './portal/pool/playwright-launcher.js';
60
52
  import { LeaseReaper } from './portal/pool/lease-reaper.js';
61
53
  import { findProjectConfig, readJournalEnabled, readProjectId, } from './command/cli/ports/resolve/cli-port.js';
62
54
  import { probeLaunchableChromium } from './launch-chromium.js';
63
55
  import { attachJournal } from './wire-journal.js';
64
56
  import { reportOnboardingStep } from './telemetry/onboarding-funnel.js';
65
- import { AMBIENT_RECORDING } from './language/flows/recording/tape/recordings.js';
66
57
  import { readRetainPolicy } from './memory/journal/on-disk/retain-policy.js';
67
58
  import { log } from './log.js';
68
- import { readReaderBundle, zeroInstallScript as zeroInstallScriptFor, } from './portal/pool/zero-install.js';
59
+ import { createBrowserPool, knownProjectRoots, loadHarnessConfig, makeNetworkDetailRouter, platformEnvFor, readerConnect, resolveRealInput, sdkFixForProject, } from './start-wiring.js';
69
60
  export { replayVerdictLine } from './language/flows/replay-from-hud.js';
70
61
  // Re-exported from the contract, where the names now live: a consumer importing the server should
71
62
  // not have to know that the vocabulary moved.
@@ -108,153 +99,7 @@ export { findContradictions } from '@reticlehq/engine/disagreement/contradiction
108
99
  /** Default localhost port for the verify HTTP endpoint (see docs/platform-integration.md). */
109
100
  export const RETICLE_VERIFY_DEFAULT_PORT = 7331;
110
101
  export { resolveBridgeSecurity } from './portal/bridge/bridge-security.js';
111
- /**
112
- * Build the shared browser pool (one headless Chromium, N capped isolated leased contexts). Lazy —
113
- * no Chromium launches until the first lease — so creating it is free even when never used.
114
- */
115
- /** Where the zero-install reader connects: this daemon's own bridge, with its pairing token. */
116
- function readerConnect(port, token) {
117
- return { url: bridgeWsUrl(port), ...(token === undefined ? {} : { token }) };
118
- }
119
- function createBrowserPool(headless, reader) {
120
- const maxContexts = resolveMaxContexts(process.env[ReticleEnv.MAX_CONTEXTS], cpus().length);
121
- const genSessionId = () => `lease-${'function' === typeof globalThis.crypto?.randomUUID
122
- ? globalThis.crypto.randomUUID()
123
- : String(Date.now())}`;
124
- // Built on first use and kept: the page that needs it is one whose app never connected.
125
- let script;
126
- const zeroInstallScript = () => {
127
- if (script === undefined) {
128
- const bundle = readReaderBundle();
129
- script = bundle === undefined ? null : zeroInstallScriptFor(bundle, reader);
130
- }
131
- return script ?? undefined;
132
- };
133
- return new BrowserPool(playwrightLauncher({ headless }), {
134
- maxContexts,
135
- genSessionId,
136
- zeroInstallScript,
137
- launchHeaded: playwrightLauncher({ headless: false }),
138
- });
139
- }
140
- /**
141
- * Route CDP-authoritative network detail onto the driven session's journal.
142
- *
143
- * The page and the SDK session share an origin, so a NET_DETAIL is pushed to the matching connected
144
- * session. Shared by both entry points: `startDaemon` previously omitted it entirely, so on the path
145
- * users actually take, CDP network detail was collected and then dropped on the floor.
146
- */
147
- function makeNetworkDetailRouter(bridge, driveUrl) {
148
- const driveOrigin = originOf(driveUrl ?? '');
149
- return (detail) => {
150
- // Route by the DOCUMENT that issued the request, not by the request's own origin.
151
- //
152
- // Matching the request's origin only works for same-origin calls. An app on one origin calling an
153
- // API on another — most API calls — produced a detail matching no session, and it was dropped
154
- // without a trace. The drive-URL fallback papered over it on the launched path and did nothing on
155
- // the CDP-attach path, where driveUrl is undefined and the fallback compares against ''.
156
- const pageOrigin = originOf(detail.pageUrl ?? '');
157
- const requestOrigin = originOf(detail.url);
158
- for (const session of bridge.sessions.all()) {
159
- const origin = originOf(session.url);
160
- // originOf returns `string | undefined`, NEVER '' — so the old `!== ''` guards were dead, and a
161
- // bare `origin === requestOrigin` matched `undefined === undefined` when BOTH the session URL and
162
- // the detail URL were unparseable. That routed a NET_DETAIL (with its response headers, incl.
163
- // set-cookie) onto an unrelated session. Require a DEFINED origin; undefined operands then simply
164
- // fail to match any of the three candidates.
165
- const matches = origin !== undefined &&
166
- (origin === pageOrigin || origin === requestOrigin || origin === driveOrigin);
167
- if (matches) {
168
- session.pushEvent({
169
- t: 0,
170
- type: EventType.NET_DETAIL,
171
- sessionId: session.id,
172
- data: { ...detail },
173
- });
174
- }
175
- }
176
- };
177
- }
178
- /**
179
- * Resolve the drive/real-input provider from options — shared by start and startDaemon so the
180
- * precedence (driveUrl launch+own → CDP attach → none) and the storageState/injectConnect plumbing
181
- * live in ONE place. `onNavigateError` is the entrypoint's own cleanup (close the bridge/shared server)
182
- * so a failed launch never leaks a WS port. A past divergence between the two paths let daemon mode
183
- * run with a different setup — this removes that risk.
184
- */
185
- async function resolveRealInput(options, onNavigateError, onNetworkDetail) {
186
- const driveUrl = options.driveUrl;
187
- if (driveUrl !== undefined && driveUrl.length > 0) {
188
- const headless = options.headless ?? true;
189
- // The one place that knows. Everything downstream reads it rather than re-deriving it, and a
190
- // daemon that launches nothing keeps the default (ATTACHED) rather than guessing.
191
- setBrowserMode(headless ? BrowserMode.HEADLESS : BrowserMode.HEADED);
192
- const injectConnect = options.injectConnect;
193
- const storageState = options.storageState;
194
- const factory = options.realInputFactory ??
195
- ((opts) => new LaunchedRealInputProvider({
196
- driveUrl: opts.driveUrl,
197
- headless: opts.headless,
198
- ...(injectConnect !== undefined ? { injectConnect } : {}),
199
- ...(storageState !== undefined ? { storageState } : {}),
200
- ...(onNetworkDetail !== undefined ? { onNetworkDetail } : {}),
201
- }));
202
- const launched = factory({ driveUrl, headless });
203
- try {
204
- await launched.navigate();
205
- }
206
- catch (error) {
207
- await onNavigateError(); // no leaked WS port on a failed start
208
- throw error;
209
- }
210
- return { realInput: launched, owned: launched };
211
- }
212
- const cdpUrl = options.cdpUrl ?? process.env[ReticleEnv.CDP_URL];
213
- if (cdpUrl !== undefined && cdpUrl.length > 0) {
214
- // Same network sink as the launched path. Whether Reticle opened the browser or attached to one
215
- // someone else opened has no bearing on whether it can read that browser's network.
216
- const cdp = new CdpRealInputProvider({
217
- cdpUrl,
218
- ...(onNetworkDetail !== undefined ? { onNetworkDetail } : {}),
219
- });
220
- return { realInput: cdp, owned: cdp };
221
- }
222
- return {};
223
- }
224
102
  /** Start the Reticle bridge (browser WS endpoint) and, by default, the MCP stdio server. */
225
- /**
226
- * The SDK-upgrade sentence for the package.json of the project the page announced, evaluated at
227
- * each HELLO so a just-edited manifest is what we name. The daemon's cwd only when that project's
228
- * directory is unknown, and the framework-neutral sensor when that is not an app either (#1135).
229
- */
230
- function sdkFixForProject(projectId) {
231
- return sdkFixForDirectory(SERVER_VERSION, projectDirectoryFor(projectId) ?? process.cwd());
232
- }
233
- /**
234
- * Resolve a session's artifact root, from everything this machine knows about where projects live.
235
- *
236
- * Built once per daemon and closed over by every tool call. The two sources are read lazily and
237
- * cheaply on each call rather than snapshotted at startup: `init` can run in another terminal while
238
- * this daemon is up, and a resolution that used a startup snapshot would keep answering with a map
239
- * from before the project the agent is now driving existed.
240
- */
241
- /**
242
- * Every `.reticle` root on this machine that sync should consider, from the same two sources the
243
- * artifact resolver uses.
244
- *
245
- * Read on every call rather than snapshotted, for the same reason: `reticle link` can run in
246
- * another terminal while this daemon is up, and a startup snapshot would keep that repo silent
247
- * until somebody restarted a process they have no reason to suspect.
248
- *
249
- * Returns directories that MIGHT be linked; the caller resolves each and skips the ones that are
250
- * not. Deciding that here would mean reading every cloud.json on every tick.
251
- */
252
- function knownProjectRoots() {
253
- return [...new Set(knownProjectCandidates().map((c) => join(c.directory, ReticleDir.ROOT)))];
254
- }
255
- /** This project's platform credential (stored, else the env key), as the env the platform readers take. */
256
- const platformEnvFor = (root) => platformEnvPort(createNodeFileSystem(), root ?? join(process.cwd(), ReticleDir.ROOT), homedir(), process.env);
257
- const loadHarnessConfig = async (root) => fetchPlatformConfig(await platformEnvFor(root)());
258
103
  export async function start(options = {}) {
259
104
  const port = options.port ?? RETICLE_DEFAULT_PORT;
260
105
  const configForRoot = harnessConfigsByRoot(loadHarnessConfig);
@@ -309,7 +154,7 @@ export async function start(options = {}) {
309
154
  enabled: journalEnabled,
310
155
  retain,
311
156
  // Bound HERE, where the recorder is already in hand: teardown gets the tape, not the recorder.
312
- takeAmbientTape: () => recordings.stop(AMBIENT_RECORDING),
157
+ takeAmbientTape: (sessionId) => recordings.takeAmbient(sessionId),
313
158
  reportStep: reportOnboardingStep,
314
159
  flows,
315
160
  author: flowAuthor,
@@ -423,11 +268,11 @@ export async function startDaemon(options = {}) {
423
268
  sdkFix: sdkFixForProject,
424
269
  ...security,
425
270
  });
426
- const repaint = (only) => {
271
+ const repaint = (only, ifChanged = false) => {
427
272
  for (const session of bridge.sessions.all()) {
428
273
  const root = session.artifactRoot ?? options.reticleRoot ?? join(process.cwd(), ReticleDir.ROOT);
429
- if (only === undefined || only === root)
430
- session.pushImpact(() => impactSnapshot(root), true);
274
+ if ((only ?? root) === root)
275
+ pushIfMoved(session, () => impactSnapshot(root), ifChanged);
431
276
  }
432
277
  };
433
278
  pushHarnessConfig = repaint;
@@ -446,7 +291,7 @@ export async function startDaemon(options = {}) {
446
291
  // `init` holds the daemon it is waiting on, so the idle rule cannot shut it down mid-wait.
447
292
  if (held)
448
293
  noteSetupHold(Date.now());
449
- return statusPayload(bridge.sessions.count(), bridge.sessions.list(), bridge.sessions.noSessionHint(), verifyHttp?.port, bridge.sessions.noSessionLead());
294
+ return statusPayload(bridge.sessions.count(), bridge.sessions.list(), bridge.sessions.noSessionHint(), verifyHttp?.port, bridge.sessions.noSessionLead(), bridge.sessions.all());
450
295
  });
451
296
  // Agent-independent presence: the daemon outlives any single agent, so when the LAST agent's MCP
452
297
  // connection drops (it stopped, or is waiting on the human), end every session and push a clear
@@ -469,7 +314,8 @@ export async function startDaemon(options = {}) {
469
314
  const retain = readRetainPolicy(findProjectConfig(process.cwd()));
470
315
  // See the sibling path: `retain.sessions: 0` stops the capture too, not only the sweep.
471
316
  const journalEnabled = readJournalEnabled(process.cwd(), process.env[ReticleEnv.JOURNAL]) && 0 < retain.sessions;
472
- const flows = new FlowStore(fs, reticleRoot, { now });
317
+ // A saved flow wakes sync like a landed run: see FlowStore's `onWrote`.
318
+ const flows = new FlowStore(fs, reticleRoot, { now }, { onWrote: () => syncNudge.run?.() });
473
319
  // Built here rather than inside `deps` below, so teardown can save what a drive recorded. Both
474
320
  // paths pass the same pair — `daemon-parity.test.ts` is what keeps them from drifting apart.
475
321
  const recordings = new RecordingStore(() => currentDrivenBy() !== undefined);
@@ -481,12 +327,12 @@ export async function startDaemon(options = {}) {
481
327
  * setup ahead of session capture for the sake of one callback.
482
328
  */
483
329
  const syncNudge = {};
484
- attachJournal(bridge, {
330
+ const endLiveSessions = attachJournal(bridge, {
485
331
  fs,
486
332
  reticleRoot,
487
333
  enabled: journalEnabled,
488
334
  retain,
489
- takeAmbientTape: () => recordings.stop(AMBIENT_RECORDING),
335
+ takeAmbientTape: (sessionId) => recordings.takeAmbient(sessionId),
490
336
  reportStep: reportOnboardingStep,
491
337
  flows,
492
338
  author: flowAuthor,
@@ -522,20 +368,15 @@ export async function startDaemon(options = {}) {
522
368
  otherRoots: knownProjectRoots,
523
369
  });
524
370
  syncNudge.run = () => cloudSync.nudge();
525
- // `syncNow`, not `nudge`: a nudge schedules a cycle soon, which is right for "a run landed" and
526
- // wrong for a button somebody is watching. Never awaited.
371
+ // `syncNow`, not `nudge` (a cycle soon): somebody is watching the button. Never awaited.
527
372
  bridge.attachSyncRequest(() => void cloudSync.syncNow());
528
- // The panel's harness switch, written through to the platform so console and panel cannot disagree.
529
373
  if (options.hudSignIn !== undefined)
530
- bridge.attachSigninRequest(options.hudSignIn(() => repaint()));
531
- // logout and link run in another process: repaint when their files change. See account-watch.ts.
532
- const accountFiles = watchAccountFiles(() => repaint());
374
+ bridge.attachSigninRequest(options.hudSignIn(repaint, projectLinkOnly(options.hudLink)));
375
+ // Logout and link run in another process: repaint when their files change, the rest on a timer.
376
+ const accountFiles = watchAccountFiles(repaint, undefined, () => repaint(undefined, true));
533
377
  accountFiles.watch(join(homedir(), ReticleDir.ROOT, SESSION_FILE));
534
378
  bridge.attachSessionReady((s) => accountFiles.watch(join(s.artifactRoot ?? reticleRoot, ReticleDir.CLOUD_LINK_FILE)));
535
- bridge.attachHarnessRequest((on, s) => {
536
- const root = s.artifactRoot ?? reticleRoot;
537
- applyHarnessSwitch(configForRoot, root, on, platformEnvFor(root));
538
- });
379
+ attachHudHarness(bridge, { deps: () => deps, root: reticleRoot, repaint: () => repaint() }, (r, on) => applyHarnessSwitch(configForRoot, r, on, platformEnvFor(r)), options.hudLink);
539
380
  // Scope auto-selection to the active project (from .reticle.json) so a stray tab from another app is
540
381
  // never picked when the agent omits a sessionId. Explicit per-call scope/sessionId still overrides.
541
382
  // Scope + the no-session diagnosis: "no browser session connected" is the error that ends most
@@ -544,6 +385,7 @@ export async function startDaemon(options = {}) {
544
385
  // server for a wired project (see no-session-watch.ts), and it opens it through the pool — the same
545
386
  // path reticle_lease takes, in this process, binding nothing.
546
387
  wireSessionScope(bridge.sessions, readProjectId(process.cwd()), port, (sessionId) => pool.wasReapedLease(sessionId), (url) => pool.acquire(url));
388
+ const leaseUrl = (url) => runTool(LEASE_ACQUIRE_TOOL, effectiveDeps, { url });
547
389
  const deps = {
548
390
  sessions: bridge.sessions,
549
391
  pool,
@@ -568,7 +410,7 @@ export async function startDaemon(options = {}) {
568
410
  now,
569
411
  bridgePort: port,
570
412
  browserProbe: probeLaunchableChromium,
571
- firstRun: firstRunWiring({ port, cliPath: process.argv[1] ?? '' }),
413
+ ...agentWiring(port, bridge.sessions, leaseUrl),
572
414
  // A finished verification should not sit behind a one-minute timer — see ToolDeps.onRunPersisted.
573
415
  onRunPersisted: () => cloudSync.nudge(),
574
416
  syncNow: () => cloudSync.syncNow(),
@@ -580,12 +422,12 @@ export async function startDaemon(options = {}) {
580
422
  shared.attachMcp((peerSkew) => createMcpServer(peerSkew === undefined
581
423
  ? effectiveDeps
582
424
  : { ...effectiveDeps, peerSkew: connectionSkew(peerSkew) }, profile, instructionStateAt(port, bridge.sessions.count())));
583
- // `reticle drive <url>` against this daemon's port, through runTool. See cli/drive/drive-attach.ts.
584
- shared.attachDrive((url) => runTool(LEASE_ACQUIRE_TOOL, effectiveDeps, { url }));
425
+ shared.attachDrive(leaseUrl); // `reticle drive <url>` — see cli/drive/drive-attach.ts.
585
426
  // The platform chat's apps and drives, run here. See chat-drives.ts.
586
427
  const chatDrives = startChatDrives(effectiveDeps, bridge.sessions, fs, {
587
428
  sessionCloud: sessionCloudPort(fs, homedir(), process.env, (id) => sessionRoot(effectiveDeps, id)),
588
429
  version: SERVER_VERSION,
430
+ unsynced: () => cloudSync.unsyncedRoots(),
589
431
  }, log);
590
432
  // Optional OEM/CI verify endpoint: a host platform POSTs to /verify and gets an ReticleVerificationRun,
591
433
  // driving the same flow-replay machinery the agent uses — no MCP stdio, no human. Each verdict is
@@ -678,6 +520,7 @@ export async function startDaemon(options = {}) {
678
520
  leaseReaper.stop();
679
521
  chatDrives.stop();
680
522
  accountFiles.close();
523
+ await endLiveSessions(); // first: an open tab's teardown writes the flow this flush sends
681
524
  await cloudSync.flush(); // not stop(): the last run written is the one nobody has yet
682
525
  await loopbackAlias.close?.();
683
526
  await pool.shutdown();
@@ -45,9 +45,9 @@ declare const CapsuleSchema: z.ZodObject<{
45
45
  version: 1;
46
46
  id: string;
47
47
  origin: string;
48
+ createdAt: number;
48
49
  expected: string;
49
50
  steps: FlowStep[];
50
- createdAt: number;
51
51
  observed: string;
52
52
  flow?: string | undefined;
53
53
  seen?: number | undefined;
@@ -56,9 +56,9 @@ declare const CapsuleSchema: z.ZodObject<{
56
56
  version: 1;
57
57
  id: string;
58
58
  origin: string;
59
+ createdAt: number;
59
60
  expected: string;
60
61
  steps: FlowStep[];
61
- createdAt: number;
62
62
  observed: string;
63
63
  flow?: string | undefined;
64
64
  seen?: number | undefined;
@@ -40,10 +40,24 @@ export interface CausalSummary {
40
40
  headline?: string;
41
41
  };
42
42
  consoleErrors: number;
43
+ /** The first console error's text, capped — so a count is never the only thing an agent can read. */
44
+ firstConsoleError?: string;
45
+ /**
46
+ * The app's requests in this window as `METHOD /path STATUS` (`pending` when unanswered), capped.
47
+ * Origin and query string are left out: the line is for recognising the call, and the full record is
48
+ * one `reticle_observe { since }` away. Present only when there were any.
49
+ */
50
+ requests?: string[];
43
51
  statePathsChanged: string[];
44
52
  storageKeysChanged: string[];
45
53
  /** Before→after for each changed store path — the diffs, not just the names. Values capped. */
46
54
  stateDiffs: StateDiff[];
55
+ /**
56
+ * How many store diffs were left out of `stateDiffs` because they moved only a cache's own
57
+ * bookkeeping (fetchStatus, isStale, dataUpdatedAt — see engine's state-bookkeeping rule). Present
58
+ * only when there were any: a trim is never silent. Predicates still see every transition.
59
+ */
60
+ ignoredBookkeeping?: number;
47
61
  /**
48
62
  * How long the store took to stop moving: last state change − first, in ms. Present only when more
49
63
  * than one path changed, because with a single change there is no interval to describe.
@@ -126,6 +140,6 @@ interface SummaryContext {
126
140
  */
127
141
  export declare const MAX_SUMMARY_ENTRIES = 20;
128
142
  /** The lists that are capped, named so `elided` can say which one lost entries. */
129
- type CappedList = 'statePathsChanged' | 'storageKeysChanged' | 'stateDiffs' | 'storageDiffs' | 'signals' | 'fieldsChanged';
143
+ type CappedList = 'requests' | 'statePathsChanged' | 'storageKeysChanged' | 'stateDiffs' | 'storageDiffs' | 'signals' | 'fieldsChanged';
130
144
  export declare function causalSummary(events: readonly ReticleEvent[], context?: SummaryContext): CausalSummary;
131
145
  export {};
@@ -1,5 +1,6 @@
1
1
  import { EventType, PerfMetric, isDevToolingUrl } from '@reticlehq/core';
2
2
  import { routeOfEvent } from '@reticlehq/engine/question/predicate/predicate-route.js';
3
+ import { isCacheBookkeepingDiff } from '@reticlehq/engine/evidence/state-bookkeeping.js';
3
4
  /**
4
5
  * THE INVARIANT: every field of this summary has a bounded size that does not depend on how much the
5
6
  * app did. A verdict travels in the same payload as its evidence, so an unbounded evidence field is
@@ -57,12 +58,34 @@ function stateSettle(diffs) {
57
58
  const spread = Math.max(...times) - Math.min(...times);
58
59
  return spread > 0 ? { stateSettleMs: spread } : {};
59
60
  }
61
+ /** `METHOD /path STATUS` — what an agent recognises a call by. */
62
+ function requestLine(data) {
63
+ const raw = 'string' === typeof data['url'] ? data['url'] : '';
64
+ let path;
65
+ try {
66
+ path = new URL(raw, 'http://local.invalid').pathname;
67
+ }
68
+ catch {
69
+ path = raw.split('?')[0] ?? raw;
70
+ }
71
+ const method = 'string' === typeof data['method'] ? data['method'].toUpperCase() : 'GET';
72
+ const status = 'number' === typeof data['status'] ? String(data['status']) : 'pending';
73
+ return `${method} ${path} ${status}`;
74
+ }
75
+ /** The first line of a console error, capped. */
76
+ function firstLine(data) {
77
+ const text = ['message', 'text', 'error'].map((k) => data[k]).find((v) => 'string' === typeof v);
78
+ const line = ('string' === typeof text ? text : 'console error').split('\n')[0] ?? '';
79
+ return truncate(line);
80
+ }
60
81
  export function causalSummary(events, context = {}) {
61
82
  let netTotal = 0;
62
83
  let netErrors = 0;
63
84
  let ignoredDevTooling = 0;
64
85
  let headline;
65
86
  let consoleErrors = 0;
87
+ let firstConsoleError;
88
+ const requests = [];
66
89
  const statePathsChanged = [];
67
90
  const storageKeysChanged = [];
68
91
  const stateDiffs = [];
@@ -72,6 +95,7 @@ export function causalSummary(events, context = {}) {
72
95
  const fieldsChanged = [];
73
96
  let layoutShift;
74
97
  let longTasks = 0;
98
+ let ignoredBookkeeping = 0;
75
99
  for (const event of events) {
76
100
  const data = event.data;
77
101
  switch (event.type) {
@@ -82,6 +106,7 @@ export function causalSummary(events, context = {}) {
82
106
  }
83
107
  netTotal += 1;
84
108
  const status = data['status'];
109
+ requests.push(requestLine(data));
85
110
  const failed = false === data['ok'] || ('number' === typeof status && status >= 400);
86
111
  if (failed) {
87
112
  netErrors += 1;
@@ -93,6 +118,7 @@ export function causalSummary(events, context = {}) {
93
118
  case EventType.CONSOLE_ERROR:
94
119
  case EventType.ERROR_UNCAUGHT:
95
120
  consoleErrors += 1;
121
+ firstConsoleError ??= firstLine(data);
96
122
  break;
97
123
  case EventType.STATE_CHANGE: {
98
124
  pushUnique(statePathsChanged, data['name']);
@@ -103,6 +129,10 @@ export function causalSummary(events, context = {}) {
103
129
  const hasAfter = 'value' in data || 'new' in data;
104
130
  if ('string' === typeof path && path.length > 0 && ('old' in data || hasAfter)) {
105
131
  const after = 'value' in data ? data['value'] : data['new'];
132
+ if (isCacheBookkeepingDiff(data['old'], after)) {
133
+ ignoredBookkeeping += 1;
134
+ break;
135
+ }
106
136
  stateDiffs.push({
107
137
  path,
108
138
  from: capValue(data['old']),
@@ -160,9 +190,12 @@ export function causalSummary(events, context = {}) {
160
190
  ...(headline === undefined ? {} : { headline }),
161
191
  },
162
192
  consoleErrors,
193
+ ...(firstConsoleError === undefined ? {} : { firstConsoleError }),
194
+ ...(0 === requests.length ? {} : { requests: cap(requests, 'requests', elided) }),
163
195
  statePathsChanged: cap(statePathsChanged, 'statePathsChanged', elided),
164
196
  storageKeysChanged: cap(storageKeysChanged, 'storageKeysChanged', elided),
165
197
  stateDiffs: cap(stateDiffs, 'stateDiffs', elided),
198
+ ...(0 === ignoredBookkeeping ? {} : { ignoredBookkeeping }),
166
199
  ...settle,
167
200
  storageDiffs: cap(storageDiffs, 'storageDiffs', elided),
168
201
  ...(route === undefined ? {} : { route }),
@@ -25,7 +25,7 @@ export type VerificationRunInput = Omit<ReticleVerificationRun, 'schemaVersion'
25
25
  * reason those two values now survive into the artifact instead of being dropped at its door.
26
26
  * Confidence: nothing ran → LOW; an oracle-backed flow or any check ran → HIGH; only smoke → MEDIUM.
27
27
  */
28
- export declare function computeVerdict(input: VerificationRunInput): RunVerdict;
28
+ export declare function computeVerdict(raw: VerificationRunInput): RunVerdict;
29
29
  /**
30
30
  * Assemble the final, schema-valid ReticleVerificationRun. Stamps schemaVersion + createdAt (injected
31
31
  * clock) and computes the verdict; the result is parsed through the protocol schema so a malformed
@@ -8,6 +8,7 @@
8
8
  */
9
9
  import { ReticleVerificationRunSchema, RUN_FILE_VERSION, Verified, RunConfidence, RunFlowStatus, VerdictStatus, } from '@reticlehq/core';
10
10
  import { redactForProfile } from './profile-redact.js';
11
+ import { supersededChecks } from '@reticlehq/engine/evidence/superseded-checks.js';
11
12
  /**
12
13
  * Compute the verdict deterministically from the run's flows, checks, and risks.
13
14
  * Rules (in order): a gated risk blocks → FAIL; mixed pass+fail → PARTIAL; any fail → FAIL;
@@ -18,12 +19,23 @@ import { redactForProfile } from './profile-redact.js';
18
19
  * reason those two values now survive into the artifact instead of being dropped at its door.
19
20
  * Confidence: nothing ran → LOW; an oracle-backed flow or any check ran → HIGH; only smoke → MEDIUM.
20
21
  */
21
- export function computeVerdict(input) {
22
+ export function computeVerdict(raw) {
23
+ // A passive check that read too early is superseded by the same claim holding later: the one
24
+ // rule every fold applies (superseded-checks.ts).
25
+ const superseded = supersededChecks(raw.checks.map((c) => ({
26
+ key: c.predicate,
27
+ passive: false === c.declaredBeforeActing,
28
+ held: Verified.YES === c.status,
29
+ failed: Verified.NO === c.status,
30
+ })));
31
+ const input = { ...raw, checks: raw.checks.filter((_, at) => !superseded.has(at)) };
22
32
  const passes = input.flows.filter((f) => f.status === RunFlowStatus.PASS || f.status === RunFlowStatus.HEALED)
23
33
  .length + input.checks.filter((c) => c.status === Verified.YES).length;
24
34
  const fails = input.flows.filter((f) => f.status === RunFlowStatus.FAIL).length +
25
35
  input.checks.filter((c) => c.status === Verified.NO).length;
26
36
  const skippedFlows = input.flows.filter((f) => f.status === RunFlowStatus.SKIPPED).length;
37
+ // Ran and decided nothing, as the agent's own result block counts them: never part of a pass.
38
+ const undecidedChecks = input.checks.filter((c) => c.status !== Verified.YES && c.status !== Verified.NO).length;
27
39
  const blockingRisks = input.risks.filter((r) => r.gated).length;
28
40
  const reasons = [];
29
41
  for (const f of input.flows) {
@@ -47,12 +59,16 @@ export function computeVerdict(input) {
47
59
  let status;
48
60
  if (blockingRisks > 0)
49
61
  status = VerdictStatus.FAIL;
50
- else if (fails > 0 && passes > 0)
51
- status = VerdictStatus.PARTIAL;
62
+ // A failure beside things that passed is a fail, not a partial: the result block, the CLI and the
63
+ // platform's grade all call it that, and a "partial" beside "Reticle result: failed" was one run
64
+ // with two verdicts. A partial is only ever a pass with something skipped or undecided beside it.
52
65
  else if (fails > 0)
53
66
  status = VerdictStatus.FAIL;
54
- else if (skippedFlows > 0 && passes > 0)
67
+ else if ((skippedFlows > 0 || undecidedChecks > 0) && passes > 0) {
55
68
  status = VerdictStatus.PARTIAL;
69
+ if (0 < undecidedChecks)
70
+ reasons.push(`${String(undecidedChecks)} check(s) undecided`);
71
+ }
56
72
  else if (0 === passes) {
57
73
  // Nothing passed and nothing failed, so nothing was proved -- an empty run, or one whose every
58
74
  // flow was skipped. Reporting that as PASS is the false green this whole file exists to prevent:
@@ -1,21 +1,3 @@
1
- /**
2
- * The gap, as a number the person who ran the session can see.
3
- *
4
- * Reticle's whole claim is that it measures the distance between what an agent believed happened
5
- * and what did. It measures that on every verdict, writes the answer into the journal, and shows it
6
- * to nobody: the counts exist, the reasons exist, the contradictions exist, and no surface anywhere
7
- * says "you made 14 claims, 9 held, 2 were false, 3 could not be decided, and here is who owns each
8
- * of those three". The value of the product is the one thing it never reports.
9
- *
10
- * A FOLD over the journal, never a second store — the rule `run-context.ts` next door states, for
11
- * the same reason: two ways to compute one number is worse than one way, because the day they
12
- * disagree the disagreement lands inside a verdict and a user finds it before we do.
13
- *
14
- * Nothing here sends anything anywhere, and that is deliberate rather than incidental. This is the
15
- * LOCAL half. Whether a fleet-wide version of the same number is worth collecting is a separate
16
- * decision with a separate owner, and building the local one first is what makes that decision
17
- * answerable from something other than a guess.
18
- */
19
1
  import { VerifiedReason, VerdictAttribution, type JournalAction } from '@reticlehq/core';
20
2
  /** One claim that did not hold, in the words it was made and the engine's reason for refusing it. */
21
3
  export interface GapFailure {
@@ -16,6 +16,7 @@
16
16
  * decision with a separate owner, and building the local one first is what makes that decision
17
17
  * answerable from something other than a guess.
18
18
  */
19
+ import { supersededChecks } from '@reticlehq/engine/evidence/superseded-checks.js';
19
20
  import { JournalVerdictEffectSchema, Verified, VerifiedReason, VerdictAttribution, verdictAttributionOf, } from '@reticlehq/core';
20
21
  /**
21
22
  * The reason, as the engine's own enum, or undefined.
@@ -48,9 +49,17 @@ export function gapSummary(actions) {
48
49
  falseGreensCaught: 0,
49
50
  failures: [],
50
51
  };
51
- for (const action of actions) {
52
- const verdict = verdictOf(action);
53
- if (verdict === undefined)
52
+ const verdicts = actions.map(verdictOf).filter((v) => v !== undefined);
53
+ // A passive check that read too early is not counted: the one rule every fold applies
54
+ // (superseded-checks.ts), so this block and the run's verdict cannot disagree.
55
+ const superseded = supersededChecks(verdicts.map((v) => ({
56
+ key: v.claim,
57
+ passive: false === v.declaredBeforeActing,
58
+ held: Verified.YES === v.verified,
59
+ failed: Verified.NO === v.verified,
60
+ })));
61
+ for (const [at, verdict] of verdicts.entries()) {
62
+ if (superseded.has(at))
54
63
  continue;
55
64
  summary.claims += 1;
56
65
  switch (verdict.verified) {