e2e 0.16.0 → 0.18.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 (256) hide show
  1. package/README.md +10 -0
  2. package/dist/.build.json +1 -1
  3. package/dist/agent/act.js +7 -4
  4. package/dist/agent/action-dispatcher.js +4 -5
  5. package/dist/agent/actions.d.ts +32 -23
  6. package/dist/agent/actions.js +38 -24
  7. package/dist/agent/ai-sdk.js +5 -4
  8. package/dist/agent/error.js +3 -3
  9. package/dist/agent/invocation.js +3 -4
  10. package/dist/agent/model/sdk.js +2 -0
  11. package/dist/agent/model/tool-choice.d.ts +9 -0
  12. package/dist/agent/model/tool-choice.js +14 -0
  13. package/dist/agent/observation-feed.d.ts +5 -6
  14. package/dist/agent/observation-feed.js +8 -11
  15. package/dist/agent/observation.d.ts +40 -11
  16. package/dist/agent/observation.js +109 -59
  17. package/dist/agent/phases.d.ts +7 -1
  18. package/dist/agent/phases.js +12 -3
  19. package/dist/agent/point-tap.d.ts +8 -8
  20. package/dist/agent/point-tap.js +1 -1
  21. package/dist/agent/prompts.js +3 -0
  22. package/dist/agent/replay.d.ts +19 -8
  23. package/dist/agent/replay.js +29 -29
  24. package/dist/agent/scroll-target.d.ts +2 -3
  25. package/dist/agent/step-cache.d.ts +43 -15
  26. package/dist/agent/step-cache.js +156 -67
  27. package/dist/agent/tool-loop.js +94 -5
  28. package/dist/cache/anchors.d.ts +72 -23
  29. package/dist/cache/anchors.js +233 -60
  30. package/dist/cache/context.d.ts +25 -14
  31. package/dist/cache/context.js +50 -8
  32. package/dist/cache/decide.d.ts +2 -2
  33. package/dist/cache/decide.js +4 -6
  34. package/dist/cache/identity.d.ts +18 -4
  35. package/dist/cache/identity.js +9 -4
  36. package/dist/cache/recorder.d.ts +15 -1
  37. package/dist/cache/recorder.js +36 -23
  38. package/dist/cache/rekeyed.d.ts +46 -0
  39. package/dist/cache/rekeyed.js +89 -0
  40. package/dist/cache/relocate.d.ts +14 -14
  41. package/dist/cache/relocate.js +33 -25
  42. package/dist/cache/route.d.ts +32 -33
  43. package/dist/cache/route.js +94 -50
  44. package/dist/cache/store.d.ts +6 -0
  45. package/dist/cache/store.js +21 -1
  46. package/dist/cache/trace.d.ts +53 -14
  47. package/dist/cache/trace.js +76 -30
  48. package/dist/cli/bin.js +2 -2
  49. package/dist/cli/index.js +43 -32
  50. package/dist/cli/init/engines.d.ts +1 -3
  51. package/dist/cli/init/engines.js +2 -2
  52. package/dist/cli/init/gateways.d.ts +1 -1
  53. package/dist/cli/init/gateways.js +11 -1
  54. package/dist/cli/init/mcp-config.d.ts +2 -1
  55. package/dist/cli/init/mcp-config.js +8 -3
  56. package/dist/cli/init/sibling-versions.json +1 -1
  57. package/dist/cli/init/versions.d.ts +0 -8
  58. package/dist/cli/init/versions.js +1 -10
  59. package/dist/cli/mcp.d.ts +3 -2
  60. package/dist/cli/mcp.js +52 -16
  61. package/dist/cli/run-output.d.ts +17 -0
  62. package/dist/cli/run-output.js +45 -0
  63. package/dist/collect/collect.js +8 -4
  64. package/dist/collect/registry.js +27 -16
  65. package/dist/config/compiled-files.d.ts +36 -0
  66. package/dist/config/compiled-files.js +50 -0
  67. package/dist/config/diagnose.js +21 -19
  68. package/dist/config/esm-hooks.d.ts +39 -44
  69. package/dist/config/esm-hooks.js +238 -63
  70. package/dist/config/load.d.ts +1 -7
  71. package/dist/config/load.js +23 -66
  72. package/dist/config/register.d.ts +8 -0
  73. package/dist/config/register.js +9 -0
  74. package/dist/config/resolve.d.ts +1 -0
  75. package/dist/config/resolve.js +33 -1
  76. package/dist/config/specifiers.d.ts +19 -0
  77. package/dist/config/specifiers.js +33 -0
  78. package/dist/config/tsconfig.d.ts +56 -0
  79. package/dist/config/tsconfig.js +115 -0
  80. package/dist/config/typescript.d.ts +19 -0
  81. package/dist/config/typescript.js +253 -0
  82. package/dist/engine/contract.d.ts +1 -0
  83. package/dist/engine/index.d.ts +4 -2
  84. package/dist/engine/session.js +2 -2
  85. package/dist/expect/async.js +4 -2
  86. package/dist/expect/poll-scope.d.ts +52 -0
  87. package/dist/expect/poll-scope.js +113 -0
  88. package/dist/expect/poll.js +33 -6
  89. package/dist/expect/values.js +11 -4
  90. package/dist/internal/abandoned.d.ts +11 -0
  91. package/dist/internal/abandoned.js +23 -0
  92. package/dist/internal/brands.d.ts +2 -0
  93. package/dist/internal/brands.js +2 -0
  94. package/dist/internal/client-identity.d.ts +9 -0
  95. package/dist/internal/client-identity.js +14 -0
  96. package/dist/internal/errors.d.ts +10 -3
  97. package/dist/internal/errors.js +23 -8
  98. package/dist/internal/node-version.d.ts +16 -7
  99. package/dist/internal/node-version.js +50 -15
  100. package/dist/internal/package-manager.js +1 -1
  101. package/dist/internal/realm-slot.d.ts +5 -4
  102. package/dist/internal/redact.d.ts +9 -4
  103. package/dist/internal/redact.js +120 -23
  104. package/dist/internal/time.d.ts +26 -4
  105. package/dist/internal/time.js +58 -14
  106. package/dist/internal/urls.d.ts +9 -5
  107. package/dist/internal/urls.js +19 -10
  108. package/dist/locator/engine.d.ts +12 -2
  109. package/dist/locator/engine.js +55 -14
  110. package/dist/locator/screen.js +59 -9
  111. package/dist/mcp/catalog.d.ts +3 -2
  112. package/dist/mcp/catalog.js +6 -6
  113. package/dist/mcp/output.d.ts +59 -0
  114. package/dist/mcp/output.js +129 -0
  115. package/dist/mcp/server.d.ts +4 -0
  116. package/dist/mcp/server.js +9 -12
  117. package/dist/mcp/session.d.ts +8 -1
  118. package/dist/mcp/session.js +56 -15
  119. package/dist/mcp/tools.js +7 -5
  120. package/dist/oauth/chatgpt.js +3 -23
  121. package/dist/oauth/cli.js +1 -0
  122. package/dist/oauth/copilot.d.ts +5 -4
  123. package/dist/oauth/copilot.js +80 -7
  124. package/dist/oauth/grok.js +2 -1
  125. package/dist/oauth/models.js +2 -1
  126. package/dist/oauth/opencode-console.d.ts +10 -0
  127. package/dist/oauth/opencode-console.js +133 -0
  128. package/dist/oauth/providers/github-copilot.d.ts +12 -0
  129. package/dist/oauth/providers/github-copilot.js +77 -23
  130. package/dist/oauth/providers/opencode-console.d.ts +31 -0
  131. package/dist/oauth/providers/opencode-console.js +148 -0
  132. package/dist/oauth/providers.d.ts +2 -6
  133. package/dist/oauth/providers.js +3 -7
  134. package/dist/oauth/responses.d.ts +9 -0
  135. package/dist/oauth/responses.js +23 -0
  136. package/dist/report/build.d.ts +26 -0
  137. package/dist/report/build.js +16 -8
  138. package/dist/report/failure-text.d.ts +6 -1
  139. package/dist/report/failure-text.js +14 -4
  140. package/dist/report/format.d.ts +10 -5
  141. package/dist/report/format.js +12 -5
  142. package/dist/report/junit.js +11 -12
  143. package/dist/report/list.d.ts +12 -0
  144. package/dist/report/list.js +61 -24
  145. package/dist/report/markdown.d.ts +1 -1
  146. package/dist/report/markdown.js +37 -14
  147. package/dist/report/repeats.d.ts +6 -1
  148. package/dist/report/repeats.js +12 -3
  149. package/dist/run/artifacts.d.ts +22 -4
  150. package/dist/run/artifacts.js +71 -3
  151. package/dist/run/execute.d.ts +34 -5
  152. package/dist/run/execute.js +93 -44
  153. package/dist/run/extended-fixtures.js +6 -2
  154. package/dist/run/failure-evidence.js +10 -4
  155. package/dist/run/fixtures.js +6 -8
  156. package/dist/run/in-process.d.ts +2 -0
  157. package/dist/run/in-process.js +52 -10
  158. package/dist/run/last-run.d.ts +42 -8
  159. package/dist/run/last-run.js +121 -14
  160. package/dist/run/process-output.d.ts +73 -0
  161. package/dist/run/process-output.js +130 -0
  162. package/dist/run/provision.d.ts +2 -0
  163. package/dist/run/provision.js +1 -0
  164. package/dist/run/realm.d.ts +4 -1
  165. package/dist/run/realm.js +20 -6
  166. package/dist/run/records.d.ts +20 -4
  167. package/dist/run/records.js +26 -0
  168. package/dist/run/retry.d.ts +10 -1
  169. package/dist/run/retry.js +30 -12
  170. package/dist/run/runner.d.ts +9 -1
  171. package/dist/run/runner.js +101 -39
  172. package/dist/run/scheduler.js +255 -19
  173. package/dist/run/secrecy.d.ts +22 -19
  174. package/dist/run/secrecy.js +22 -18
  175. package/dist/run/serial.d.ts +75 -2
  176. package/dist/run/serial.js +243 -59
  177. package/dist/run/standalone.js +1 -1
  178. package/dist/run/steps.d.ts +0 -6
  179. package/dist/run/steps.js +3 -20
  180. package/dist/run/trace-redaction.d.ts +5 -6
  181. package/dist/run/trace-redaction.js +5 -6
  182. package/dist/run/worker/entry.js +40 -18
  183. package/dist/run/worker/handle.js +10 -5
  184. package/dist/run/worker/protocol.d.ts +85 -3
  185. package/dist/run/worker/session.d.ts +2 -0
  186. package/dist/run/worker/session.js +29 -0
  187. package/dist/telemetry/environment.d.ts +2 -1
  188. package/dist/telemetry/environment.js +12 -2
  189. package/dist/telemetry/events.js +1 -0
  190. package/dist/telemetry/project.d.ts +5 -6
  191. package/dist/telemetry/project.js +6 -11
  192. package/dist/telemetry/store.d.ts +5 -5
  193. package/dist/telemetry/store.js +5 -7
  194. package/dist/telemetry/telemetry.d.ts +2 -3
  195. package/dist/telemetry/telemetry.js +2 -4
  196. package/dist/types.d.ts +15 -6
  197. package/docs/agent-steps.mdx +1 -0
  198. package/docs/agents.mdx +7 -3
  199. package/docs/api-testing.mdx +2 -1
  200. package/docs/authentication.mdx +6 -3
  201. package/docs/browser.mdx +49 -12
  202. package/docs/bug-bash.mdx +2 -1
  203. package/docs/cache.mdx +66 -19
  204. package/docs/ci.mdx +14 -9
  205. package/docs/coding-agents.mdx +2 -1
  206. package/docs/core-concepts.mdx +208 -0
  207. package/docs/debugging.mdx +25 -12
  208. package/docs/decision-models.mdx +142 -0
  209. package/docs/example-projects.mdx +32 -0
  210. package/docs/executors.mdx +7 -2
  211. package/docs/explore.mdx +1 -0
  212. package/docs/github.mdx +14 -5
  213. package/docs/index.mdx +9 -5
  214. package/docs/integrations/eas.mdx +1 -0
  215. package/docs/integrations/index.mdx +1 -0
  216. package/docs/integrations/kernel.mdx +3 -2
  217. package/docs/migrate/cypress.mdx +26 -3
  218. package/docs/migrate/detox.mdx +24 -1
  219. package/docs/migrate/maestro.mdx +28 -4
  220. package/docs/migrate/playwright.mdx +44 -18
  221. package/docs/migrate/selenium.mdx +27 -3
  222. package/docs/mobile-ci.mdx +6 -5
  223. package/docs/mobile.mdx +96 -8
  224. package/docs/models.mdx +60 -9
  225. package/docs/quickstart.mdx +28 -16
  226. package/docs/reference/agent.mdx +13 -3
  227. package/docs/reference/app.mdx +2 -1
  228. package/docs/reference/cli.mdx +41 -18
  229. package/docs/reference/config.mdx +67 -13
  230. package/docs/reference/engine.mdx +25 -13
  231. package/docs/reference/environment.mdx +10 -2
  232. package/docs/reference/errors.mdx +13 -10
  233. package/docs/reference/expect.mdx +36 -13
  234. package/docs/reference/mcp.mdx +21 -8
  235. package/docs/reference/mobile.mdx +24 -13
  236. package/docs/reference/reporters.mdx +9 -2
  237. package/docs/reference/screen.mdx +49 -16
  238. package/docs/reference/test.mdx +32 -5
  239. package/docs/reference/web.mdx +133 -23
  240. package/docs/security.mdx +58 -42
  241. package/docs/subscriptions.mdx +92 -12
  242. package/docs/telemetry.mdx +9 -6
  243. package/docs/tools.mdx +1 -0
  244. package/docs/{starting-your-app.mdx → web.mdx} +157 -11
  245. package/docs/writing-an-engine.mdx +2 -1
  246. package/package.json +25 -8
  247. package/schema/report-v1.schema.json +14 -1
  248. package/skills/e2e/SKILL.md +5 -3
  249. package/skills/e2e/references/agent.md +33 -11
  250. package/skills/e2e/references/debugging.md +4 -4
  251. package/skills/e2e/references/mcp.md +8 -3
  252. package/skills/e2e/references/running.md +15 -9
  253. package/skills/e2e/references/setup.md +45 -16
  254. package/skills/e2e/references/writing-tests.md +35 -18
  255. package/docs/viewports.mdx +0 -146
  256. package/docs/writing-tests.mdx +0 -256
@@ -11,7 +11,6 @@
11
11
  * timeout, cancellation) rethrow untouched; they are the step's truth, not a
12
12
  * divergence.
13
13
  */
14
- import { anchorsPresent } from '../cache/anchors.js';
15
14
  import { isRelocatableDescriptor, MAIN_LIST_SHARE, relocateDescriptor } from '../cache/relocate.js';
16
15
  import { isNodeAction } from '../cache/trace.js';
17
16
  import { hasCause } from '../internal/errors.js';
@@ -146,25 +145,30 @@ export async function replayTrace(host, trace, options = {}) {
146
145
  break;
147
146
  }
148
147
  case 'free':
148
+ if (previous !== undefined && options.looksBeforeFree?.() === true)
149
+ await firstLook(host, look);
149
150
  await planned.invoke();
150
151
  break;
151
152
  case 'scroll': {
152
- if (planned.list === undefined) {
153
- // A viewport scroll relocates nothing, so each later repeat takes
154
- // a settled look of its own, as the live loop did between them.
155
- for (let index = 0; index < planned.times; index += 1) {
153
+ // A scroll on a list is paced by the relocation before each repeat.
154
+ // A viewport scroll relocates nothing, so each later repeat takes a
155
+ // settled look of its own, as the live loop did between them. A
156
+ // list judged lost scrolls as the viewport from then on, instead of
157
+ // waiting out the relocation backoff again on every repeat.
158
+ let list = planned.list;
159
+ for (let index = 0; index < planned.times; index += 1) {
160
+ if (list === undefined) {
156
161
  if (index > 0)
157
162
  await host.observe('held-still');
158
163
  await host.actions.scroll(planned.direction);
159
- repeated += 1;
160
164
  }
161
- break;
162
- }
163
- // A scroll on a list is paced by the relocation before each repeat.
164
- for (let index = 0; index < planned.times; index += 1) {
165
- const lost = await scrollOnce(host, planned.direction, planned.list, index === 0 ? look : HELD_STILL);
166
- if (lost !== undefined)
167
- return stop(lost, partial());
165
+ else {
166
+ const scrolled = await scrollOnce(host, planned.direction, list, index === 0 ? look : HELD_STILL);
167
+ if (scrolled.kind === 'failed')
168
+ return stop(scrolled.failure, partial());
169
+ if (scrolled.kind === 'viewport')
170
+ list = undefined;
171
+ }
168
172
  repeated += 1;
169
173
  }
170
174
  break;
@@ -228,21 +232,19 @@ export async function replayTrace(host, trace, options = {}) {
228
232
  return { completed: true, executed: summaries.length, total, summaries };
229
233
  }
230
234
  /**
231
- * Verifies a trace's recorded end anchors against the live screen: every
232
- * anchor must be present again (`anchors.ts`, every recorded field equal) or
233
- * the replay must not pass on its own. Waits on the same settling backoff
235
+ * Waits for a trace's recorded end state on the live screen: `holds` (the
236
+ * recorded delta, `cache/anchors.ts`) must be true of one look, or the
237
+ * replay must not pass on its own. Waits on the same settling backoff
234
238
  * relocation uses, because the recording run's final look came seconds of
235
239
  * model latency after its last action and a replay's comes right away: a
236
240
  * save still in flight is a wait, not a divergence. A surface that cannot be
237
241
  * observed at all is a mismatch too — the executor gets the step and judges
238
242
  * the live state; only runtime hard stops propagate.
239
243
  */
240
- export async function verifyAnchors(host, anchors, options = {}) {
241
- if (anchors.length === 0)
242
- return true;
244
+ export async function verifyEndState(host, holds, options = {}) {
243
245
  const startedMs = Date.now();
244
246
  try {
245
- const present = await pollSettled(host, ({ nodes }) => anchorsPresent(anchors, nodes, host) ? true : undefined, options.initial === undefined ? HELD_STILL : { kind: 'in-hand', screen: options.initial });
247
+ const present = await pollSettled(host, (screen) => holds(screen) ? true : undefined, options.initial === undefined ? HELD_STILL : { kind: 'in-hand', screen: options.initial });
246
248
  if (present === true)
247
249
  return true;
248
250
  // The settling backoff covers a slow re-render; the recorded run may have
@@ -255,7 +257,7 @@ export async function verifyAnchors(host, anchors, options = {}) {
255
257
  const screen = await host.observe('raw');
256
258
  if (screen.kind === 'pixels' || !host.traceEligible)
257
259
  return false;
258
- if (anchorsPresent(anchors, screen.nodes, host))
260
+ if (holds(screen))
259
261
  return true;
260
262
  }
261
263
  return false;
@@ -272,10 +274,9 @@ const END_WAIT_POLL_MS = 1_000;
272
274
  const END_WAIT_RESERVE_MS = 20_000;
273
275
  /** Relocates one descriptor against the settling screen, looking again while `retryable` says the failure may pass. */
274
276
  async function relocate(host, descriptor, look) {
275
- const options = { redact: host.redact };
276
277
  let last = { kind: 'failed', failure: 'target-not-found' };
277
278
  const settled = await pollSettled(host, (screen) => {
278
- const result = relocateDescriptor(descriptor, screen.nodes, options);
279
+ const result = relocateDescriptor(descriptor, screen.nodes);
279
280
  if (result.kind === 'failed') {
280
281
  last = result.failure === 'target-not-found' ? result : { ...result, screen };
281
282
  return retryable(result.failure, descriptor) ? undefined : last;
@@ -294,17 +295,16 @@ async function relocate(host, descriptor, look) {
294
295
  * unpositioned ambiguity is not.
295
296
  */
296
297
  async function relocatePair(host, source, destination, look) {
297
- const options = { redact: host.redact };
298
298
  let last = 'target-not-found';
299
299
  const failed = (descriptor, failure) => {
300
300
  last = failure;
301
301
  return retryable(failure, descriptor) ? undefined : { kind: 'failed', failure };
302
302
  };
303
303
  const settled = await pollSettled(host, (screen) => {
304
- const from = relocateDescriptor(source, screen.nodes, options);
304
+ const from = relocateDescriptor(source, screen.nodes);
305
305
  if (from.kind === 'failed')
306
306
  return failed(source, from.failure);
307
- const to = relocateDescriptor(destination, screen.nodes, options);
307
+ const to = relocateDescriptor(destination, screen.nodes);
308
308
  if (to.kind === 'failed')
309
309
  return failed(destination, to.failure);
310
310
  return { kind: 'found', source: from.id, destination: to.id };
@@ -380,12 +380,12 @@ async function scrollOnce(host, direction, list, look) {
380
380
  const relocated = await relocate(host, list.descriptor, look);
381
381
  if (relocated.kind === 'found') {
382
382
  await host.actions.scroll(direction, { id: relocated.id });
383
- return undefined;
383
+ return { kind: 'list' };
384
384
  }
385
385
  if ((list.spans ?? 0) < MAIN_LIST_SHARE)
386
- return relocated.failure;
386
+ return { kind: 'failed', failure: relocated.failure };
387
387
  await host.actions.scroll(direction);
388
- return undefined;
388
+ return { kind: 'viewport' };
389
389
  }
390
390
  /** A fresh look that proves the screen holds still: the first look of a replay without a start capture, and the look after an action that moved the screen. */
391
391
  const HELD_STILL = { kind: 'capture', settle: 'held-still' };
@@ -10,11 +10,10 @@
10
10
  * all scrolls as the viewport does, which is what scrolling the main list
11
11
  * does; a smaller region that vanished is gone, as for any other action.
12
12
  */
13
- import type { SemanticNode } from '../engine/surface.ts';
14
13
  import { type Box } from '../internal/geometry.ts';
15
14
  import type { ExecutorTarget } from './executor.ts';
16
15
  import { type ObservationFeed, type Resolved } from './observation-feed.ts';
17
- import type { SemanticAgentObservation } from './observation.ts';
16
+ import type { RedactedNode, SemanticAgentObservation } from './observation.ts';
18
17
  /**
19
18
  * The node a scroll target names now: the node itself, its descriptor's
20
19
  * match, or the same-role node in its old place. Undefined for a lost list
@@ -22,4 +21,4 @@ import type { SemanticAgentObservation } from './observation.ts';
22
21
  */
23
22
  export declare function resolveScrollTarget(feed: ObservationFeed, target: ExecutorTarget): Resolved | undefined;
24
23
  /** The listed node of the role whose box overlaps `box` most, when it overlaps enough. */
25
- export declare function samePlace(observation: SemanticAgentObservation, role: string | undefined, box: Box): SemanticNode | undefined;
24
+ export declare function samePlace(observation: SemanticAgentObservation, role: string | undefined, box: Box): RedactedNode | undefined;
@@ -12,6 +12,7 @@
12
12
  * when replay performed no action.
13
13
  */
14
14
  import type { AgentCacheContext } from '../cache/context.ts';
15
+ import type { CacheAgentIdentity } from '../cache/identity.ts';
15
16
  import { type ParamTemplate } from '../cache/template.ts';
16
17
  import { type DerivedReason } from '../cache/trace.ts';
17
18
  import type { StepCacheInfo } from '../run/steps.ts';
@@ -42,7 +43,11 @@ export interface StepCacheOptions {
42
43
  readonly name: string;
43
44
  readonly version?: string;
44
45
  };
46
+ /** The agent the step runs with, part of the key (`cache/identity.ts`). */
47
+ readonly agent: CacheAgentIdentity;
45
48
  readonly redact: (text: string) => string;
49
+ /** `redact` for a field cut at its observed limit (`SecretLedger.redactCut`). */
50
+ readonly redactCut: (text: string) => string;
46
51
  readonly maxActions: number;
47
52
  /** Timeline index of the step being dispatched. */
48
53
  readonly stepIndex: number;
@@ -60,8 +65,11 @@ export declare class StepTraceSession {
60
65
  private readonly host;
61
66
  private readonly cache;
62
67
  private readonly keyHash;
68
+ /** The claimed key and the step it names, which an entry records as its provenance. */
69
+ private readonly claim;
63
70
  private readonly recorder;
64
71
  private readonly options;
72
+ private readonly redaction;
65
73
  private info;
66
74
  private prefix;
67
75
  private startPath;
@@ -85,6 +93,8 @@ export declare class StepTraceSession {
85
93
  private replayedWhole;
86
94
  /** True once a cached entry's actions were run this step, fully or partly. */
87
95
  private consumedReplay;
96
+ /** True once the store returned an entry for this step, whether or not it replayed. */
97
+ private readEntryHit;
88
98
  /** True once `cache.strict` failed the step on its recording, which is then kept for review rather than evicted. */
89
99
  private failedStale;
90
100
  /** Grammar actions recorded so far when an end-mismatch hand-off happened. */
@@ -107,7 +117,8 @@ export declare class StepTraceSession {
107
117
  * self-finalized verdict on a full replay whose postcondition holds;
108
118
  * undefined dispatches the executor — after a miss from the top, after a
109
119
  * divergence mid-step with `replayedPrefix` set. Every failure to replay is
110
- * a miss, never an error; only runtime hard stops propagate.
120
+ * a miss, never an error; only runtime hard stops and a policy denial on
121
+ * the opening look propagate.
111
122
  */
112
123
  begin(): Promise<StepVerdict | undefined>;
113
124
  /**
@@ -117,6 +128,14 @@ export declare class StepTraceSession {
117
128
  * model call to absorb on every run. The report keeps the cache detail.
118
129
  */
119
130
  private failIfStale;
131
+ /**
132
+ * Under `cache.strict`, ends a step whose key found no entry while the
133
+ * store holds a recording made for the same step under another key: the
134
+ * runner, the engine, the app, or the agent's context changed since, and
135
+ * the recording no longer replays as surely as one that diverged. A step
136
+ * whose instruction or params changed is a new step and still runs live.
137
+ */
138
+ private failIfRekeyed;
120
139
  /**
121
140
  * Closes the session once the step has settled. The whole write-side
122
141
  * decision lives here, in read-write mode only:
@@ -136,6 +155,10 @@ export declare class StepTraceSession {
136
155
  * anchor, or end wait, so drift is repaired only once a relocation fails
137
156
  * and the hand-off that follows re-records.
138
157
  * - passed otherwise: stage the recorded trace for attempt-end settlement.
158
+ * When this pass leaves nothing to stage (it changed nothing a replay
159
+ * could check) and an entry was read for the step, evict that entry: it
160
+ * did not serve this pass, and nothing recorded will replace it, so
161
+ * keeping it would hand every later run off the same way.
139
162
  * - failed after consuming a replay: evict. Without this, a diverged replay
140
163
  * whose step then fails stages nothing — and the poisoned entry would
141
164
  * replay its bad prefix on every future first attempt.
@@ -172,18 +195,22 @@ export declare class StepTraceSession {
172
195
  private replayEntry;
173
196
  /**
174
197
  * The trace's postcondition against the live screen: the recorded end
175
- * route (when the live location is known) and every recorded end anchor
176
- * present again. A route the path leaves undecided is the recorded screen
177
- * only if the anchors are already on it, which then needs no second look.
198
+ * route when the live location is known, the recorded delta on the
199
+ * screen (`deltaHolds`), and evidence that the replay produced it rather
200
+ * than finding it there (`deltaEvidenced`). The evidence is measured from
201
+ * the first screen the replay saw on the route it ended on (`screens`, in
202
+ * order): the start for a step that stays on one screen, the page a
203
+ * recorded navigate opened before the switch on it was tapped. An outcome
204
+ * already showing there proves nothing, and neither does a recording with
205
+ * no delta at all.
178
206
  */
179
207
  private endStateMatches;
180
208
  /**
181
209
  * Captures the semantic end state once its route matches the recording,
182
- * polling while a navigation the last action started commits. Reports
183
- * whether the anchors were what settled the route, so the caller does not
184
- * verify them again. A route still undecided when the poll runs out is
185
- * handed on with the anchors unseen: the caller's anchor wait, sized by
186
- * the recording, is the one that decides it, as for a route that matched.
210
+ * polling while a navigation the last action started commits. A route
211
+ * that never matches is another screen, whatever it shows: a link that
212
+ * now lands on a page sharing the recorded one's layout is exactly the
213
+ * flow that went wrong.
187
214
  */
188
215
  private endScreen;
189
216
  private selfFinalize;
@@ -199,12 +226,13 @@ export declare class StepTraceSession {
199
226
  *
200
227
  * The end path and a fresh settled observation are the trace's
201
228
  * postcondition — the state the step passed in. The delta between the
202
- * baseline and the passing observation becomes the end anchors. When the
203
- * step moved to another pathname the whole new screen is the delta, and its
204
- * first stable anchors back the path check, which matches a created
205
- * record's page up to the id the app minted for it. A postcondition that
206
- * cannot be captured stages nothing: a trace without its check would
207
- * replay on mechanics alone.
229
+ * baseline and the passing observation becomes the anchors: what appeared
230
+ * and what vanished. When the step moved to another pathname the whole new
231
+ * screen is the delta, and its first stable anchors back the path check,
232
+ * which matches a created record's page up to the id the app minted for
233
+ * it. A postcondition that cannot be captured stages nothing, and neither
234
+ * does a step that changed nothing a replay could check, no node and no
235
+ * route: a trace without its check would replay on mechanics alone.
208
236
  */
209
237
  private stage;
210
238
  /**