@descryy/mcp 0.5.0 → 0.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 (260) hide show
  1. package/dist/action-handshake.d.ts +8 -75
  2. package/dist/action-handshake.d.ts.map +1 -1
  3. package/dist/action-handshake.js +9 -79
  4. package/dist/action-handshake.js.map +1 -1
  5. package/dist/bin/descry-mcp.d.ts +4 -15
  6. package/dist/bin/descry-mcp.d.ts.map +1 -1
  7. package/dist/bin/descry-mcp.js +12 -42
  8. package/dist/bin/descry-mcp.js.map +1 -1
  9. package/dist/browser/driver.d.ts +62 -178
  10. package/dist/browser/driver.d.ts.map +1 -1
  11. package/dist/browser/driver.js +14 -46
  12. package/dist/browser/driver.js.map +1 -1
  13. package/dist/browser/evidence.d.ts +11 -35
  14. package/dist/browser/evidence.d.ts.map +1 -1
  15. package/dist/browser/evidence.js +25 -51
  16. package/dist/browser/evidence.js.map +1 -1
  17. package/dist/browser/fake-driver.d.ts +12 -16
  18. package/dist/browser/fake-driver.d.ts.map +1 -1
  19. package/dist/browser/fake-driver.js +24 -17
  20. package/dist/browser/fake-driver.js.map +1 -1
  21. package/dist/browser/graph-write.d.ts +4 -45
  22. package/dist/browser/graph-write.d.ts.map +1 -1
  23. package/dist/browser/graph-write.js +8 -53
  24. package/dist/browser/graph-write.js.map +1 -1
  25. package/dist/browser/playwright-driver.d.ts +17 -67
  26. package/dist/browser/playwright-driver.d.ts.map +1 -1
  27. package/dist/browser/playwright-driver.js +169 -166
  28. package/dist/browser/playwright-driver.js.map +1 -1
  29. package/dist/browser/provider.d.ts +5 -34
  30. package/dist/browser/provider.d.ts.map +1 -1
  31. package/dist/browser/provider.js +4 -24
  32. package/dist/browser/provider.js.map +1 -1
  33. package/dist/browser/registry.d.ts +26 -106
  34. package/dist/browser/registry.d.ts.map +1 -1
  35. package/dist/browser/registry.js +20 -77
  36. package/dist/browser/registry.js.map +1 -1
  37. package/dist/browser/scenario-resolve.d.ts +10 -44
  38. package/dist/browser/scenario-resolve.d.ts.map +1 -1
  39. package/dist/browser/scenario-resolve.js +10 -41
  40. package/dist/browser/scenario-resolve.js.map +1 -1
  41. package/dist/browser/scenario-runner.d.ts +12 -70
  42. package/dist/browser/scenario-runner.d.ts.map +1 -1
  43. package/dist/browser/scenario-runner.js +33 -91
  44. package/dist/browser/scenario-runner.js.map +1 -1
  45. package/dist/browser/stack-parser.d.ts +4 -28
  46. package/dist/browser/stack-parser.d.ts.map +1 -1
  47. package/dist/browser/stack-parser.js +12 -39
  48. package/dist/browser/stack-parser.js.map +1 -1
  49. package/dist/browser/tool-support.d.ts +20 -67
  50. package/dist/browser/tool-support.d.ts.map +1 -1
  51. package/dist/browser/tool-support.js +22 -66
  52. package/dist/browser/tool-support.js.map +1 -1
  53. package/dist/browser/url-scheme.d.ts +14 -0
  54. package/dist/browser/url-scheme.d.ts.map +1 -0
  55. package/dist/browser/url-scheme.js +38 -0
  56. package/dist/browser/url-scheme.js.map +1 -0
  57. package/dist/cancellation.d.ts +11 -46
  58. package/dist/cancellation.d.ts.map +1 -1
  59. package/dist/cancellation.js +11 -46
  60. package/dist/cancellation.js.map +1 -1
  61. package/dist/capped.d.ts +17 -0
  62. package/dist/capped.d.ts.map +1 -0
  63. package/dist/capped.js +15 -0
  64. package/dist/capped.js.map +1 -0
  65. package/dist/disclosure-ledger.d.ts +6 -30
  66. package/dist/disclosure-ledger.d.ts.map +1 -1
  67. package/dist/disclosure-ledger.js +4 -26
  68. package/dist/disclosure-ledger.js.map +1 -1
  69. package/dist/index.d.ts +10 -26
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +7 -17
  72. package/dist/index.js.map +1 -1
  73. package/dist/module-trust.d.ts +24 -0
  74. package/dist/module-trust.d.ts.map +1 -0
  75. package/dist/module-trust.js +60 -0
  76. package/dist/module-trust.js.map +1 -0
  77. package/dist/path-confinement.d.ts +31 -0
  78. package/dist/path-confinement.d.ts.map +1 -0
  79. package/dist/path-confinement.js +44 -0
  80. package/dist/path-confinement.js.map +1 -0
  81. package/dist/protocol.d.ts +10 -53
  82. package/dist/protocol.d.ts.map +1 -1
  83. package/dist/protocol.js +14 -60
  84. package/dist/protocol.js.map +1 -1
  85. package/dist/registry.d.ts +10 -58
  86. package/dist/registry.d.ts.map +1 -1
  87. package/dist/registry.js +38 -90
  88. package/dist/registry.js.map +1 -1
  89. package/dist/render.d.ts +79 -11
  90. package/dist/render.d.ts.map +1 -1
  91. package/dist/render.js +126 -14
  92. package/dist/render.js.map +1 -1
  93. package/dist/runtime-registry.d.ts +8 -49
  94. package/dist/runtime-registry.d.ts.map +1 -1
  95. package/dist/runtime-registry.js +72 -63
  96. package/dist/runtime-registry.js.map +1 -1
  97. package/dist/scenarios/index.d.ts +1 -1
  98. package/dist/scenarios/index.d.ts.map +1 -1
  99. package/dist/scenarios/index.js +1 -1
  100. package/dist/scenarios/index.js.map +1 -1
  101. package/dist/scenarios/parse.d.ts +4 -18
  102. package/dist/scenarios/parse.d.ts.map +1 -1
  103. package/dist/scenarios/parse.js +14 -34
  104. package/dist/scenarios/parse.js.map +1 -1
  105. package/dist/scenarios/scenario.d.ts +18 -74
  106. package/dist/scenarios/scenario.d.ts.map +1 -1
  107. package/dist/scenarios/scenario.js +7 -34
  108. package/dist/scenarios/scenario.js.map +1 -1
  109. package/dist/scenarios/storage.d.ts +11 -41
  110. package/dist/scenarios/storage.d.ts.map +1 -1
  111. package/dist/scenarios/storage.js +57 -47
  112. package/dist/scenarios/storage.js.map +1 -1
  113. package/dist/server.d.ts.map +1 -1
  114. package/dist/server.js +55 -13
  115. package/dist/server.js.map +1 -1
  116. package/dist/session.d.ts +69 -239
  117. package/dist/session.d.ts.map +1 -1
  118. package/dist/session.js +76 -231
  119. package/dist/session.js.map +1 -1
  120. package/dist/tools/analyze.d.ts +27 -101
  121. package/dist/tools/analyze.d.ts.map +1 -1
  122. package/dist/tools/analyze.js +58 -148
  123. package/dist/tools/analyze.js.map +1 -1
  124. package/dist/tools/browser-click.d.ts +3 -21
  125. package/dist/tools/browser-click.d.ts.map +1 -1
  126. package/dist/tools/browser-click.js +10 -31
  127. package/dist/tools/browser-click.js.map +1 -1
  128. package/dist/tools/browser-close-session.d.ts +4 -13
  129. package/dist/tools/browser-close-session.d.ts.map +1 -1
  130. package/dist/tools/browser-close-session.js +4 -13
  131. package/dist/tools/browser-close-session.js.map +1 -1
  132. package/dist/tools/browser-fill.d.ts +5 -36
  133. package/dist/tools/browser-fill.d.ts.map +1 -1
  134. package/dist/tools/browser-fill.js +9 -44
  135. package/dist/tools/browser-fill.js.map +1 -1
  136. package/dist/tools/browser-navigate.d.ts +6 -27
  137. package/dist/tools/browser-navigate.d.ts.map +1 -1
  138. package/dist/tools/browser-navigate.js +6 -23
  139. package/dist/tools/browser-navigate.js.map +1 -1
  140. package/dist/tools/browser-run-scenario.d.ts +5 -31
  141. package/dist/tools/browser-run-scenario.d.ts.map +1 -1
  142. package/dist/tools/browser-run-scenario.js +10 -46
  143. package/dist/tools/browser-run-scenario.js.map +1 -1
  144. package/dist/tools/browser-save-scenario.d.ts +3 -28
  145. package/dist/tools/browser-save-scenario.d.ts.map +1 -1
  146. package/dist/tools/browser-save-scenario.js +102 -55
  147. package/dist/tools/browser-save-scenario.js.map +1 -1
  148. package/dist/tools/browser-snapshot.d.ts +6 -39
  149. package/dist/tools/browser-snapshot.d.ts.map +1 -1
  150. package/dist/tools/browser-snapshot.js +4 -31
  151. package/dist/tools/browser-snapshot.js.map +1 -1
  152. package/dist/tools/browser-start-session.d.ts +4 -23
  153. package/dist/tools/browser-start-session.d.ts.map +1 -1
  154. package/dist/tools/browser-start-session.js +38 -51
  155. package/dist/tools/browser-start-session.js.map +1 -1
  156. package/dist/tools/browser-type.d.ts +5 -35
  157. package/dist/tools/browser-type.d.ts.map +1 -1
  158. package/dist/tools/browser-type.js +10 -45
  159. package/dist/tools/browser-type.js.map +1 -1
  160. package/dist/tools/contracts.d.ts +17 -63
  161. package/dist/tools/contracts.d.ts.map +1 -1
  162. package/dist/tools/contracts.js +91 -47
  163. package/dist/tools/contracts.js.map +1 -1
  164. package/dist/tools/cross-pr.d.ts +56 -15
  165. package/dist/tools/cross-pr.d.ts.map +1 -1
  166. package/dist/tools/cross-pr.js +141 -38
  167. package/dist/tools/cross-pr.js.map +1 -1
  168. package/dist/tools/git-diff.d.ts +18 -2
  169. package/dist/tools/git-diff.d.ts.map +1 -1
  170. package/dist/tools/git-diff.js +143 -23
  171. package/dist/tools/git-diff.js.map +1 -1
  172. package/dist/tools/git-history.d.ts +5 -16
  173. package/dist/tools/git-history.d.ts.map +1 -1
  174. package/dist/tools/git-history.js +3 -10
  175. package/dist/tools/git-history.js.map +1 -1
  176. package/dist/tools/history.d.ts +4 -33
  177. package/dist/tools/history.d.ts.map +1 -1
  178. package/dist/tools/history.js +6 -31
  179. package/dist/tools/history.js.map +1 -1
  180. package/dist/tools/impact.d.ts +7 -51
  181. package/dist/tools/impact.d.ts.map +1 -1
  182. package/dist/tools/impact.js +15 -67
  183. package/dist/tools/impact.js.map +1 -1
  184. package/dist/tools/index.d.ts +3 -8
  185. package/dist/tools/index.d.ts.map +1 -1
  186. package/dist/tools/index.js +3 -8
  187. package/dist/tools/index.js.map +1 -1
  188. package/dist/tools/kit.d.ts +66 -113
  189. package/dist/tools/kit.d.ts.map +1 -1
  190. package/dist/tools/kit.js +60 -28
  191. package/dist/tools/kit.js.map +1 -1
  192. package/dist/tools/link-workspace.d.ts +7 -45
  193. package/dist/tools/link-workspace.d.ts.map +1 -1
  194. package/dist/tools/link-workspace.js +10 -48
  195. package/dist/tools/link-workspace.js.map +1 -1
  196. package/dist/tools/lookup.d.ts +4 -14
  197. package/dist/tools/lookup.d.ts.map +1 -1
  198. package/dist/tools/lookup.js +4 -14
  199. package/dist/tools/lookup.js.map +1 -1
  200. package/dist/tools/mark-incident.d.ts +7 -54
  201. package/dist/tools/mark-incident.d.ts.map +1 -1
  202. package/dist/tools/mark-incident.js +15 -68
  203. package/dist/tools/mark-incident.js.map +1 -1
  204. package/dist/tools/observe-runtime.d.ts +27 -210
  205. package/dist/tools/observe-runtime.d.ts.map +1 -1
  206. package/dist/tools/observe-runtime.js +258 -436
  207. package/dist/tools/observe-runtime.js.map +1 -1
  208. package/dist/tools/observe-tests.d.ts +9 -88
  209. package/dist/tools/observe-tests.d.ts.map +1 -1
  210. package/dist/tools/observe-tests.js +34 -108
  211. package/dist/tools/observe-tests.js.map +1 -1
  212. package/dist/tools/pr-analysis.d.ts +18 -2
  213. package/dist/tools/pr-analysis.d.ts.map +1 -1
  214. package/dist/tools/pr-analysis.js +73 -23
  215. package/dist/tools/pr-analysis.js.map +1 -1
  216. package/dist/tools/pre-push.d.ts +94 -9
  217. package/dist/tools/pre-push.d.ts.map +1 -1
  218. package/dist/tools/pre-push.js +139 -34
  219. package/dist/tools/pre-push.js.map +1 -1
  220. package/dist/tools/propagation.d.ts +11 -53
  221. package/dist/tools/propagation.d.ts.map +1 -1
  222. package/dist/tools/propagation.js +14 -57
  223. package/dist/tools/propagation.js.map +1 -1
  224. package/dist/tools/questions.d.ts +13 -63
  225. package/dist/tools/questions.d.ts.map +1 -1
  226. package/dist/tools/questions.js +33 -105
  227. package/dist/tools/questions.js.map +1 -1
  228. package/dist/tools/refusal-fetch.d.ts +4 -40
  229. package/dist/tools/refusal-fetch.d.ts.map +1 -1
  230. package/dist/tools/refusal-fetch.js +4 -40
  231. package/dist/tools/refusal-fetch.js.map +1 -1
  232. package/dist/tools/runtime-incident.d.ts +4 -63
  233. package/dist/tools/runtime-incident.d.ts.map +1 -1
  234. package/dist/tools/runtime-incident.js +10 -87
  235. package/dist/tools/runtime-incident.js.map +1 -1
  236. package/dist/tools/scope.d.ts +7 -25
  237. package/dist/tools/scope.d.ts.map +1 -1
  238. package/dist/tools/scope.js +17 -20
  239. package/dist/tools/scope.js.map +1 -1
  240. package/dist/tools/similar-incidents.d.ts +11 -86
  241. package/dist/tools/similar-incidents.d.ts.map +1 -1
  242. package/dist/tools/similar-incidents.js +7 -71
  243. package/dist/tools/similar-incidents.js.map +1 -1
  244. package/dist/tools/validate.d.ts +31 -47
  245. package/dist/tools/validate.d.ts.map +1 -1
  246. package/dist/tools/validate.js +133 -61
  247. package/dist/tools/validate.js.map +1 -1
  248. package/dist/tools/verification-status.d.ts +9 -64
  249. package/dist/tools/verification-status.d.ts.map +1 -1
  250. package/dist/tools/verification-status.js +9 -62
  251. package/dist/tools/verification-status.js.map +1 -1
  252. package/dist/tools/verify-claim.d.ts +5 -52
  253. package/dist/tools/verify-claim.d.ts.map +1 -1
  254. package/dist/tools/verify-claim.js +6 -56
  255. package/dist/tools/verify-claim.js.map +1 -1
  256. package/dist/transport.d.ts +15 -52
  257. package/dist/transport.d.ts.map +1 -1
  258. package/dist/transport.js +16 -60
  259. package/dist/transport.js.map +1 -1
  260. package/package.json +33 -16
@@ -1,85 +1,27 @@
1
- /**
2
- * Live browser sessions belonging to one connection — `mcp-browser-tools.md`
3
- * §4.
4
- *
5
- * ## Why this is the hard part
6
- *
7
- * Every other tool on this surface is one-shot. It opens what it needs,
8
- * answers, and holds nothing; a crash in the middle costs the caller one
9
- * reply. A browser process that outlives a call is a different shape
10
- * entirely, and the failure it introduces is not "a call fails" but "a
11
- * process is still running on the developer's machine an hour after the
12
- * agent stopped caring about it".
13
- *
14
- * So the design rule here is that **there is no path on which a session stops
15
- * being tracked without its browser being closed and its evidence being
16
- * handed back**. Four paths reach that state — idle timeout, client
17
- * disconnect, crash, explicit close — and they converge on one private
18
- * function, `reap`, rather than each doing their own teardown. They were four
19
- * separate implementations in the first draft and the evidence flush was
20
- * correct on three of them.
21
- *
22
- * ## Evidence is held, not dropped, and not silently discarded either
23
- *
24
- * A timeout or a disconnect has no reply to attach evidence to. Discarding it
25
- * would be the failure rule 7 names — silently doing less — so a reaped
26
- * session leaves a `ReapedSession` record behind carrying the reason and the
27
- * final flush, and the next caller who names that id receives it instead of a
28
- * bare "unknown session". That record is what turns "your session vanished"
29
- * into "your session was idle for five minutes; here is what it saw before it
30
- * went".
31
- *
32
- * ## Per connection, never global
33
- *
34
- * A registry is created per `Session`, which is created per connection. A
35
- * global one would let a second client `use` a first client's browser by
36
- * guessing a uuid, and would make the disconnect reap ambiguous about whose
37
- * sessions it was reaping.
38
- */
1
+ /** Live browser sessions belonging to one connection — `mcp-browser-tools.md` §4. Four
2
+ * teardown paths (idle timeout, disconnect, crash, close) converge on one `reap` so a
3
+ * session never stops being tracked without its browser closing and evidence being
4
+ * flushed (kept, never dropped — rule 7). Per-connection, never global — a global
5
+ * registry would let one client guess another's browser by session id. */
39
6
  import type { BrowserDriver, BrowserLaunchOptions, BrowserObservation, BrowserPageSession, ChromiumRefusal } from "./driver.ts";
40
- /**
41
- * How long a session may go untouched before it is torn down.
42
- *
43
- * A starting value, not a measurement, in this repo's usual sense: no agent
44
- * has yet been observed pausing mid-exploration, so there is nothing to fit
45
- * it to. Five minutes is long enough to survive a model thinking, short
46
- * enough that a forgotten browser is a five-minute leak rather than an
47
- * overnight one. It is deliberately the same figure as the action handshake's
48
- * token TTL — an agent that cannot decide within one is unlikely to be coming
49
- * back for the other.
50
- */
7
+ /** How long a session may go untouched before torn down. Starting value, not a
8
+ * measurement — 5 min balances agent-thinking time against leak size; matches the
9
+ * action handshake's token TTL deliberately. */
51
10
  export declare const BROWSER_IDLE_TIMEOUT_MS: number;
52
- /**
53
- * How many sessions one connection may hold open at once.
54
- *
55
- * Small on purpose. A calling agent driving more than a couple of browsers
56
- * simultaneously is not doing something this surface was built for, and each
57
- * one is a real Chromium. Three leaves room for the honest case — a
58
- * comparison between two states, plus one being opened — without letting a
59
- * loop with a missing `browser_close_session` fill the machine.
60
- */
11
+ /** Max sessions per connection. Small on purpose — each is a real Chromium process;
12
+ * 3 leaves room for comparing two states plus one opening, without a loop with a
13
+ * missing `browser_close_session` filling the machine. */
61
14
  export declare const MAX_BROWSER_SESSIONS = 3;
62
15
  export type ReapReason = "idleTimeout" | "clientDisconnect" | "crashed" | "closed";
63
- /**
64
- * DEC-270's vocabulary, read here and defined nowhere near here.
65
- *
66
- * A browser session's safety level is the environment profile's — the same
67
- * field `observe_runtime` already reads. Declaring a second, browser-only
68
- * notion of "safe" is how a runtime run and a browser run end up disagreeing
69
- * about the same environment, which is the failure item 27 exists to prevent.
70
- * Null means no profile was supplied, in which case the session's consent is
71
- * the only authorization and it governs alone.
72
- */
16
+ /** DEC-270's vocabulary. Reuses `observe_runtime`'s environment-profile field rather
17
+ * than a browser-only notion of "safe" (item 27: two definitions could disagree).
18
+ * Null means no profile — session consent alone governs. */
73
19
  export type BrowserSafetyLevel = "readOnly" | "write" | "destructiveWithApproval";
74
20
  export interface BrowserSessionEntry {
75
21
  readonly sessionId: string;
76
- /**
77
- * The run id every R4 edge this session witnesses is stamped with.
78
- *
79
- * One per session, not one per call: an edge's `observedByRun` answers
80
- * "which run saw this", and a run that changed identity between a click and
81
- * the request it caused would make that answer meaningless.
82
- */
22
+ /** Run id every R4 edge this session witnesses is stamped with. One per session, not
23
+ * per call — a run changing identity between a click and the request it caused would
24
+ * make `observedByRun` meaningless. */
83
25
  readonly runId: string;
84
26
  readonly page: BrowserPageSession;
85
27
  /** The profile this session was opened under, or null when none was declared. */
@@ -87,14 +29,9 @@ export interface BrowserSessionEntry {
87
29
  readonly name: string;
88
30
  readonly safetyLevel: BrowserSafetyLevel;
89
31
  } | null;
90
- /**
91
- * The origin `browser_start_session` was consented for.
92
- *
93
- * Recorded at open time rather than read from the page later: the consent
94
- * ruling binds the grant to the origin the developer approved, and a page
95
- * that has since navigated is exactly the case where re-deriving it would
96
- * launder a cross-origin move into an approved one.
97
- */
32
+ /** Origin `browser_start_session` was consented for, recorded at open time — a page
33
+ * that navigated since would let re-deriving it launder a cross-origin move into an
34
+ * approved one. */
98
35
  readonly consentedOrigin: string;
99
36
  readonly openedAt: number;
100
37
  readonly lastUsedAt: number;
@@ -140,35 +77,18 @@ export interface BrowserSessionRegistryOptions {
140
77
  readonly now?: () => number;
141
78
  readonly maxSessions?: number;
142
79
  readonly idleTimeoutMs?: number;
143
- /**
144
- * Whether to run the background idle sweep.
145
- *
146
- * True in production: a session that goes idle because the agent wandered
147
- * off is precisely the session that will never trigger a lazy sweep, so the
148
- * timeout cannot be enforced only on the next call. The timer is `unref`'d,
149
- * so it never holds the process open by itself.
150
- *
151
- * False in tests, which drive `sweepIdle()` against an injected clock —
152
- * a real timer would make the idle assertions take real minutes.
153
- */
80
+ /** Runs the background idle sweep. True in production — an idle session needs a
81
+ * timer since it will never trigger a lazy sweep on its own; timer is `unref`'d.
82
+ * False in tests, which drive `sweepIdle()` against an injected clock. */
154
83
  readonly startSweeper?: boolean;
155
84
  }
156
85
  export interface BrowserSessionRegistry {
157
86
  readonly idleTimeoutMs: number;
158
87
  readonly maxSessions: number;
159
88
  open(driver: BrowserDriver, options: BrowserOpenOptions): Promise<OpenResult>;
160
- /**
161
- * Look a session up for use, touching its idle clock. Detects a crash
162
- * before handing anything back.
163
- *
164
- * Asynchronous because the crash path is not a lookup — it is a teardown.
165
- * A synchronous `use` would have to either drop the dead page's final
166
- * evidence or pretend to have collected it, and the first draft of this
167
- * file did the second: it returned a record it then filled in from a
168
- * floating promise, so the flush landed after the caller had already read
169
- * the record. Awaiting the reap here is what makes "a crash flushes what
170
- * preceded it" true rather than nearly true.
171
- */
89
+ /** Looks up a session, touching its idle clock; detects a crash before returning.
90
+ * Async because the crash path is a teardown, not a lookup — a sync version would
91
+ * drop the dead page's evidence or (as the first draft did) flush it too late. */
172
92
  use(sessionId: string): Promise<UseResult>;
173
93
  close(sessionId: string): Promise<BrowserObservation>;
174
94
  sweepIdle(): Promise<readonly ReapedSession[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/browser/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/browser/registry.ts"],"names":[],"mappings":"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"}
@@ -1,63 +1,16 @@
1
- /**
2
- * Live browser sessions belonging to one connection — `mcp-browser-tools.md`
3
- * §4.
4
- *
5
- * ## Why this is the hard part
6
- *
7
- * Every other tool on this surface is one-shot. It opens what it needs,
8
- * answers, and holds nothing; a crash in the middle costs the caller one
9
- * reply. A browser process that outlives a call is a different shape
10
- * entirely, and the failure it introduces is not "a call fails" but "a
11
- * process is still running on the developer's machine an hour after the
12
- * agent stopped caring about it".
13
- *
14
- * So the design rule here is that **there is no path on which a session stops
15
- * being tracked without its browser being closed and its evidence being
16
- * handed back**. Four paths reach that state — idle timeout, client
17
- * disconnect, crash, explicit close — and they converge on one private
18
- * function, `reap`, rather than each doing their own teardown. They were four
19
- * separate implementations in the first draft and the evidence flush was
20
- * correct on three of them.
21
- *
22
- * ## Evidence is held, not dropped, and not silently discarded either
23
- *
24
- * A timeout or a disconnect has no reply to attach evidence to. Discarding it
25
- * would be the failure rule 7 names — silently doing less — so a reaped
26
- * session leaves a `ReapedSession` record behind carrying the reason and the
27
- * final flush, and the next caller who names that id receives it instead of a
28
- * bare "unknown session". That record is what turns "your session vanished"
29
- * into "your session was idle for five minutes; here is what it saw before it
30
- * went".
31
- *
32
- * ## Per connection, never global
33
- *
34
- * A registry is created per `Session`, which is created per connection. A
35
- * global one would let a second client `use` a first client's browser by
36
- * guessing a uuid, and would make the disconnect reap ambiguous about whose
37
- * sessions it was reaping.
38
- */
1
+ /** Live browser sessions belonging to one connection — `mcp-browser-tools.md` §4. Four
2
+ * teardown paths (idle timeout, disconnect, crash, close) converge on one `reap` so a
3
+ * session never stops being tracked without its browser closing and evidence being
4
+ * flushed (kept, never dropped — rule 7). Per-connection, never global — a global
5
+ * registry would let one client guess another's browser by session id. */
39
6
  import { EMPTY_OBSERVATION } from "./driver.js";
40
- /**
41
- * How long a session may go untouched before it is torn down.
42
- *
43
- * A starting value, not a measurement, in this repo's usual sense: no agent
44
- * has yet been observed pausing mid-exploration, so there is nothing to fit
45
- * it to. Five minutes is long enough to survive a model thinking, short
46
- * enough that a forgotten browser is a five-minute leak rather than an
47
- * overnight one. It is deliberately the same figure as the action handshake's
48
- * token TTL — an agent that cannot decide within one is unlikely to be coming
49
- * back for the other.
50
- */
7
+ /** How long a session may go untouched before torn down. Starting value, not a
8
+ * measurement — 5 min balances agent-thinking time against leak size; matches the
9
+ * action handshake's token TTL deliberately. */
51
10
  export const BROWSER_IDLE_TIMEOUT_MS = 5 * 60 * 1000;
52
- /**
53
- * How many sessions one connection may hold open at once.
54
- *
55
- * Small on purpose. A calling agent driving more than a couple of browsers
56
- * simultaneously is not doing something this surface was built for, and each
57
- * one is a real Chromium. Three leaves room for the honest case — a
58
- * comparison between two states, plus one being opened — without letting a
59
- * loop with a missing `browser_close_session` fill the machine.
60
- */
11
+ /** Max sessions per connection. Small on purpose — each is a real Chromium process;
12
+ * 3 leaves room for comparing two states plus one opening, without a loop with a
13
+ * missing `browser_close_session` filling the machine. */
61
14
  export const MAX_BROWSER_SESSIONS = 3;
62
15
  const SWEEP_INTERVAL_MS = 30_000;
63
16
  function originOf(url) {
@@ -65,9 +18,8 @@ function originOf(url) {
65
18
  return new URL(url).origin;
66
19
  }
67
20
  catch {
68
- // An unparseable target is the tool's problem, not the registry's — it
69
- // refuses at the schema. Recording the raw string keeps the consent
70
- // comparison total rather than throwing from a bookkeeping call.
21
+ // Unparseable target already refused at the schema; return the raw string so
22
+ // consent comparison stays total instead of throwing from a bookkeeping call.
71
23
  return url;
72
24
  }
73
25
  }
@@ -77,14 +29,9 @@ export function createBrowserSessionRegistry(options = {}) {
77
29
  const idleTimeoutMs = options.idleTimeoutMs ?? BROWSER_IDLE_TIMEOUT_MS;
78
30
  const live = new Map();
79
31
  const reapedSessions = new Map();
80
- /**
81
- * The one teardown. Every path goes through here so that "closed the
82
- * browser" and "kept what it saw" cannot come apart.
83
- *
84
- * `close()` on the port returns the final flush and is idempotent, so a
85
- * crashed session still yields whatever it had buffered — which is the case
86
- * that matters most, the page's last words before it died.
87
- */
32
+ /** The one teardown; every path routes through here so "closed" and "evidence kept"
33
+ * cannot come apart. `close()` on the port is idempotent, so even a crashed session
34
+ * yields its last buffered evidence. */
88
35
  async function reap(sessionId, session, reason) {
89
36
  live.delete(sessionId);
90
37
  let observation = EMPTY_OBSERVATION;
@@ -92,9 +39,8 @@ export function createBrowserSessionRegistry(options = {}) {
92
39
  observation = await session.page.close();
93
40
  }
94
41
  catch {
95
- // A teardown that throws must not leave the session tracked, and must
96
- // not lose the record either. The browser may well be gone already;
97
- // what matters is that this id is now unusable and says why.
42
+ // Teardown that throws must not leave the session tracked or lose the record —
43
+ // the browser may be gone already; this id is now unusable and says why.
98
44
  }
99
45
  const record = { sessionId, reason, observation, at: now() };
100
46
  reapedSessions.set(sessionId, record);
@@ -115,9 +61,7 @@ export function createBrowserSessionRegistry(options = {}) {
115
61
  return {
116
62
  opened: false,
117
63
  kind: "atCapacity",
118
- // Both numbers, because "too many browser sessions" is not
119
- // something a caller can act on and "3 of 3" is — it tells them
120
- // whether to close one or to stop opening them in a loop.
64
+ // Both numbers so the caller knows whether to close one or stop opening in a loop.
121
65
  reason: `This connection already has ${live.size} of ${maxSessions} browser sessions open. Close one with ` +
122
66
  "browser_close_session before starting another. The cap is per connection and exists because each " +
123
67
  "session is a real browser process.",
@@ -155,8 +99,7 @@ export function createBrowserSessionRegistry(options = {}) {
155
99
  };
156
100
  }
157
101
  if (!session.page.isUsable()) {
158
- // Down the same teardown every other path uses, so the crash case
159
- // cannot be the one where the flush is skipped.
102
+ // Same teardown as every other path, so the crash case can't skip the flush.
160
103
  const record = await reap(sessionId, session, "crashed");
161
104
  return { ok: false, kind: "crashed", reason: crashReason(sessionId), reaped: record };
162
105
  }
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/browser/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/browser/registry.ts"],"names":[],"mappings":"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"}
@@ -1,43 +1,14 @@
1
- /**
2
- * Turning a stored target descriptor back into something clickable —
3
- * `DEC-383` §2 and §3.
4
- *
5
- * This is where the anti-rot mechanism actually lives. A stored step carries
6
- * `role` + `name` + `selector` and no `ref`, because a ref is scoped to the
7
- * snapshot that issued it and a replay is always a later session. So every
8
- * step re-resolves against a fresh snapshot, and the resolution is
9
- * **exact-or-refuse**: exactly one element matching all three fields, or stop.
10
- *
11
- * **There is deliberately no fallback chain.** "Try the selector, else
12
- * role+name" is the dangerous option and it is dangerous in a specific way: it
13
- * turns a real disagreement into a quiet substitution, which is how a scenario
14
- * keeps reporting green against a page that changed underneath it. A
15
- * disagreement between the three fields is the highest-value signal this
16
- * format can produce, and a fallback is exactly the code that throws it away.
17
- *
18
- * The refusal messages are load-bearing rather than decorative, per
19
- * `DEC-384`: a stopped push that says "step 3
20
- * failed to resolve" is what developers route around, and one that says "the
21
- * button is still there; its accessible name changed from Delete to Remove" is
22
- * a one-line fix. So every refusal names which step, which descriptor, which
23
- * of the three fields disagreed, and what the page holds now.
24
- *
25
- * Lives beside the port rather than in `scenarios/`, on purpose: the format
26
- * module imports nothing from the driver and is tested without a browser in
27
- * the process, and this function needs a `PageSnapshot`.
28
- */
1
+ /** Turning a stored target descriptor back into something clickable — DEC-383 §2/§3. Stored
2
+ * steps carry role+name+selector, no `ref` (scoped to the issuing snapshot); resolution is
3
+ * exact-or-refuse against a fresh snapshot, deliberately no fallback chain — substituting one
4
+ * matching field for another turns a real disagreement into a quiet one, and the scenario
5
+ * keeps reporting green against a changed page. Refusal messages name the exact disagreement (DEC-384). */
29
6
  import type { TargetDescriptor } from "../scenarios/index.ts";
30
7
  import type { PageSnapshot, SnapshotElement } from "./driver.ts";
31
8
  export type DescriptorField = "role" | "name" | "selector";
32
- /**
33
- * Why a descriptor did not resolve.
34
- *
35
- * Three kinds, kept apart because they send a developer to three different
36
- * places. `zero` — nothing on the page answers to this at all. `ambiguous` —
37
- * several do, and picking one would be reporting on a run nobody chose.
38
- * `partial` — something is still there and one part of the descriptor has
39
- * moved, which is the case worth the most and the reason `disagreed` exists.
40
- */
9
+ /** Why a descriptor failed to resolve. `zero` — nothing matches at all. `ambiguous` —
10
+ * several do, picking one would report on an unchosen run. `partial` — something still
11
+ * matches part of it, the case `disagreed` exists for. */
41
12
  export interface ResolutionFailure {
42
13
  readonly kind: "zero" | "ambiguous" | "partial";
43
14
  /** Which of role/name/selector no longer agree. Empty for `zero` and `ambiguous`, where nothing partial matched to disagree with. */
@@ -51,12 +22,7 @@ export type TargetResolution = {
51
22
  readonly resolved: false;
52
23
  readonly failure: ResolutionFailure;
53
24
  };
54
- /**
55
- * Resolve one stored descriptor against a fresh snapshot.
56
- *
57
- * `where` is the caller's label for the thing being resolved — `"step 0"`,
58
- * `"assertion 2"` — and it is required rather than optional because a refusal
59
- * that does not say *which* step is the version this ruling exists to avoid.
60
- */
25
+ /** Resolves one stored descriptor against a fresh snapshot. `where` labels what's being
26
+ * resolved ("step 0") and is required — a refusal not saying which step is the failure this exists to avoid. */
61
27
  export declare function resolveTarget(where: string, target: TargetDescriptor, snapshot: PageSnapshot): TargetResolution;
62
28
  //# sourceMappingURL=scenario-resolve.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scenario-resolve.d.ts","sourceRoot":"","sources":["../../src/browser/scenario-resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEjE,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;AAE3D;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;IAChD,qIAAqI;IACrI,QAAQ,CAAC,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAA;CAAE,GAC9D;IAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAuBtE;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,QAAQ,EAAE,YAAY,GAAG,gBAAgB,CAgF/G"}
1
+ {"version":3,"file":"scenario-resolve.d.ts","sourceRoot":"","sources":["../../src/browser/scenario-resolve.ts"],"names":[],"mappings":"AAAA;;;;4GAI4G;AAE5G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEjE,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;AAE3D;;2DAE2D;AAC3D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;IAChD,qIAAqI;IACrI,QAAQ,CAAC,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAA;CAAE,GAC9D;IAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAuBtE;iHACiH;AACjH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,QAAQ,EAAE,YAAY,GAAG,gBAAgB,CA6E/G"}
@@ -1,31 +1,8 @@
1
- /**
2
- * Turning a stored target descriptor back into something clickable —
3
- * `DEC-383` §2 and §3.
4
- *
5
- * This is where the anti-rot mechanism actually lives. A stored step carries
6
- * `role` + `name` + `selector` and no `ref`, because a ref is scoped to the
7
- * snapshot that issued it and a replay is always a later session. So every
8
- * step re-resolves against a fresh snapshot, and the resolution is
9
- * **exact-or-refuse**: exactly one element matching all three fields, or stop.
10
- *
11
- * **There is deliberately no fallback chain.** "Try the selector, else
12
- * role+name" is the dangerous option and it is dangerous in a specific way: it
13
- * turns a real disagreement into a quiet substitution, which is how a scenario
14
- * keeps reporting green against a page that changed underneath it. A
15
- * disagreement between the three fields is the highest-value signal this
16
- * format can produce, and a fallback is exactly the code that throws it away.
17
- *
18
- * The refusal messages are load-bearing rather than decorative, per
19
- * `DEC-384`: a stopped push that says "step 3
20
- * failed to resolve" is what developers route around, and one that says "the
21
- * button is still there; its accessible name changed from Delete to Remove" is
22
- * a one-line fix. So every refusal names which step, which descriptor, which
23
- * of the three fields disagreed, and what the page holds now.
24
- *
25
- * Lives beside the port rather than in `scenarios/`, on purpose: the format
26
- * module imports nothing from the driver and is tested without a browser in
27
- * the process, and this function needs a `PageSnapshot`.
28
- */
1
+ /** Turning a stored target descriptor back into something clickable — DEC-383 §2/§3. Stored
2
+ * steps carry role+name+selector, no `ref` (scoped to the issuing snapshot); resolution is
3
+ * exact-or-refuse against a fresh snapshot, deliberately no fallback chain — substituting one
4
+ * matching field for another turns a real disagreement into a quiet one, and the scenario
5
+ * keeps reporting green against a changed page. Refusal messages name the exact disagreement (DEC-384). */
29
6
  const FIELDS = ["role", "name", "selector"];
30
7
  function describe(target) {
31
8
  return `role "${target.role}", name "${target.name}", selector "${target.selector}"`;
@@ -44,13 +21,8 @@ function pageContents(snapshot, limit = 8) {
44
21
  function disagreementsWith(target, element) {
45
22
  return FIELDS.filter((field) => element[field] !== target[field]);
46
23
  }
47
- /**
48
- * Resolve one stored descriptor against a fresh snapshot.
49
- *
50
- * `where` is the caller's label for the thing being resolved — `"step 0"`,
51
- * `"assertion 2"` — and it is required rather than optional because a refusal
52
- * that does not say *which* step is the version this ruling exists to avoid.
53
- */
24
+ /** Resolves one stored descriptor against a fresh snapshot. `where` labels what's being
25
+ * resolved ("step 0") and is required — a refusal not saying which step is the failure this exists to avoid. */
54
26
  export function resolveTarget(where, target, snapshot) {
55
27
  const exact = snapshot.elements.filter((e) => e.role === target.role && e.name === target.name && e.selector === target.selector);
56
28
  if (exact.length === 1)
@@ -81,10 +53,8 @@ export function resolveTarget(where, target, snapshot) {
81
53
  },
82
54
  };
83
55
  }
84
- // The partial case, and the reason the format stores all three fields. Both
85
- // halves are reported when both matched, because "the selector still points
86
- // at something AND an element with this role and name still exists" is two
87
- // candidates and a person is the one who knows which is theirs.
56
+ // The partial case — why the format stores all three fields. Both halves are reported
57
+ // when both matched, since two candidates exist and only a person knows which is theirs.
88
58
  const parts = [];
89
59
  const disagreed = new Set();
90
60
  if (bySelector.length === 1) {
@@ -114,8 +84,7 @@ export function resolveTarget(where, target, snapshot) {
114
84
  resolved: false,
115
85
  failure: {
116
86
  kind: "partial",
117
- // Ordered the way the descriptor is, so a caller comparing two failures
118
- // is comparing sets rather than orderings.
87
+ // Ordered like the descriptor, so callers compare sets, not orderings.
119
88
  disagreed: FIELDS.filter((field) => disagreed.has(field)),
120
89
  message: `${where}: ${describe(target)} does not match exactly one element on ${snapshot.url}, but part of it ` +
121
90
  `still does — ${parts.join("; ")}. The step is not run: substituting the half that still matches would ` +
@@ -1 +1 @@
1
- {"version":3,"file":"scenario-resolve.js","sourceRoot":"","sources":["../../src/browser/scenario-resolve.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scenario-resolve.js","sourceRoot":"","sources":["../../src/browser/scenario-resolve.ts"],"names":[],"mappings":"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"}
@@ -1,44 +1,7 @@
1
1
  /**
2
- * Replaying a stored scenario — §7's runner half.
3
- *
4
- * ## What this composes, and the four things it must not get wrong
5
- *
6
- * Everything below is composition: the port drives, `scenarios/` is the
7
- * artifact, `scenario-resolve.ts` re-resolves a descriptor, `tool-support.ts`
8
- * drains and correlates. What the runner adds is *order*, and four ordering
9
- * mistakes each fail as flakiness or as a false pass rather than as an error,
10
- * which is why each is named here rather than left to be rediscovered.
11
- *
12
- * 1. **`registry.use()` is called once per step.** It is not a lookup: it is
13
- * asynchronous, it is the crash detector, and it touches the idle clock. A
14
- * runner that resolved the session once and held the entry across N steps
15
- * would be reaped mid-scenario at the five-minute idle timeout, and would
16
- * read as a flaky test rather than as a design error.
17
- * 2. **`drainEvidence()` drains, it does not peek.** Once per step, aggregated
18
- * into the summary. A single read at the end loses every earlier step's
19
- * observations — and would silently pass an assertion anchored at step 0,
20
- * which is the false green this whole feature exists to prevent.
21
- * 3. **A stored step carries no `ref`.** Every step re-resolves against a
22
- * fresh snapshot, exact-or-refuse, with no fallback chain. See
23
- * `scenario-resolve.ts`.
24
- * 4. **Assertions evaluate here, at replay.** An empty assertion list replays
25
- * as `unverified`, never `passed`.
26
- *
27
- * ## The outcome rule
28
- *
29
- * `DEC-384`, implemented rather than restated. A
30
- * failed assertion is the scenario's own claim about the application, written
31
- * down by a person, and it blocks. A console error or a failed request is
32
- * reported and does not block — frequently true of a working page, and a check
33
- * people disable protects nothing. No assertions is `unverified`. An
34
- * unresolvable step is **neither pass nor fail**: Descry cannot tell a
35
- * deliberate rename from a vanished button, and both produce a byte-identical
36
- * unresolvable step, so it claims neither while still stopping the run.
37
- *
38
- * Three counts, **never summed** — `failed`, `unresolved`, `unverified` — and
39
- * only failed assertions join `blockingTotal`, because folding `unresolved`
40
- * into it would re-assert through arithmetic the defect claim the ruling
41
- * refused to make in prose.
2
+ * Replays a stored scenario (§7 runner). DEC-384: failed assertion blocks; console
3
+ * error/failed request doesn't; no assertions is `unverified`; unresolvable step is
4
+ * neither pass nor fail. `registry.use()` and evidence draining run once per step only.
42
5
  */
43
6
  import type { Scenario, ScenarioActionKind, ScenarioAssertionKind } from "../scenarios/index.ts";
44
7
  import type { ToolContext } from "../tools/kit.ts";
@@ -59,18 +22,9 @@ export interface ScenarioAssertionResult {
59
22
  readonly index: number;
60
23
  readonly kind: ScenarioAssertionKind;
61
24
  readonly afterStep: number | null;
62
- /**
63
- * `unevaluable` and `notReached` are deliberately distinct from each other
64
- * and from `failed`.
65
- *
66
- * `unevaluable` is a hole in the stored artifact — a `textEquals` with
67
- * nothing to compare against. `notReached` is an assertion anchored at a
68
- * step the replay never got to. Neither is a defect claim about the
69
- * application, so neither may be reported as `failed`; only `unevaluable`
70
- * joins `unresolved`, because `notReached` is already accounted for by the
71
- * unresolved step that stopped the run and counting it twice would inflate
72
- * a count the ruling requires to stay separate.
73
- */
25
+ /** `unevaluable` = hole in the artifact (e.g. missing comparison value); `notReached`
26
+ * = anchored past where replay stopped. Neither is a defect claim; only
27
+ * `unevaluable` joins `unresolved` (notReached is already counted there). */
74
28
  readonly status: "passed" | "failed" | "unevaluable" | "notReached";
75
29
  readonly detail: string;
76
30
  }
@@ -87,16 +41,9 @@ export interface ScenarioReplay {
87
41
  readonly counts: ScenarioCounts;
88
42
  /** Only failed assertions. See this file's header for why `unresolved` is not folded in. */
89
43
  readonly blockingTotal: number;
90
- /**
91
- * 0 clean, 1 blocking findings, 2 the check could not run — `descry check`'s
92
- * existing vocabulary, computed here rather than in the CLI.
93
- *
94
- * The exit ruling governs the agentless CLI and explicitly does not govern
95
- * MCP replies, so this is data on the reply rather than a verdict in it. It
96
- * is computed in the one place that knows the outcome so the CLI box does
97
- * not become a second implementation of the same rule, drifting from this
98
- * one the first time either changes.
99
- */
44
+ /** 0 clean, 1 blocking findings, 2 could-not-run — `descry check`'s exit vocabulary,
45
+ * computed here (not in the CLI) so the two never drift. Governs the CLI only;
46
+ * this reply carries it as data, not a verdict. */
100
47
  readonly exitCode: 0 | 1 | 2;
101
48
  readonly steps: readonly ScenarioStepResult[];
102
49
  readonly assertions: readonly ScenarioAssertionResult[];
@@ -105,14 +52,9 @@ export interface ScenarioReplay {
105
52
  readonly graph: BrowserGraphWrite;
106
53
  /** Set when the session went away mid-replay — a crash, a reap, a disconnect. Null on a replay that ran to its own end. */
107
54
  readonly sessionEnded: DeadSession | null;
108
- /**
109
- * True when the call's own signal was aborted mid-replay.
110
- *
111
- * Reported rather than folded into `outcome` alone, because "stopped because
112
- * the caller cancelled" and "stopped because a step would not resolve" are
113
- * different facts about the run and only one of them says anything about the
114
- * application.
115
- */
55
+ /** True when the caller's own signal aborted mid-replay — distinct from `outcome`
56
+ * because "caller cancelled" vs "a step wouldn't resolve" are different facts,
57
+ * and only one says anything about the application. */
116
58
  readonly cancelled: boolean;
117
59
  readonly notes: readonly string[];
118
60
  }