agent-scenario-loop 0.1.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 (170) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +119 -0
  3. package/app/profile-session.ts +812 -0
  4. package/core/config-template.json +41 -0
  5. package/dist/core/agent-summary.d.ts +15 -0
  6. package/dist/core/agent-summary.js +177 -0
  7. package/dist/core/artifact-contract.d.ts +151 -0
  8. package/dist/core/artifact-contract.js +897 -0
  9. package/dist/core/artifact-layout.d.ts +56 -0
  10. package/dist/core/artifact-layout.js +61 -0
  11. package/dist/core/artifact-writer.d.ts +44 -0
  12. package/dist/core/artifact-writer.js +55 -0
  13. package/dist/core/comparison.d.ts +133 -0
  14. package/dist/core/comparison.js +294 -0
  15. package/dist/core/evidence-interpreter.d.ts +28 -0
  16. package/dist/core/evidence-interpreter.js +69 -0
  17. package/dist/core/execution-plan.d.ts +44 -0
  18. package/dist/core/execution-plan.js +95 -0
  19. package/dist/core/planner.d.ts +132 -0
  20. package/dist/core/planner.js +812 -0
  21. package/dist/core/ports.d.ts +198 -0
  22. package/dist/core/ports.js +146 -0
  23. package/dist/core/run-index.d.ts +62 -0
  24. package/dist/core/run-index.js +143 -0
  25. package/dist/core/schema-validator.d.ts +86 -0
  26. package/dist/core/schema-validator.js +407 -0
  27. package/dist/index.d.ts +11 -0
  28. package/dist/index.js +27 -0
  29. package/dist/runner/agent-device-driver.d.ts +126 -0
  30. package/dist/runner/agent-device-driver.js +168 -0
  31. package/dist/runner/agent-device.d.ts +295 -0
  32. package/dist/runner/agent-device.js +1271 -0
  33. package/dist/runner/android-adb-driver.d.ts +175 -0
  34. package/dist/runner/android-adb-driver.js +399 -0
  35. package/dist/runner/android-adb.d.ts +254 -0
  36. package/dist/runner/android-adb.js +1618 -0
  37. package/dist/runner/argent-driver.d.ts +183 -0
  38. package/dist/runner/argent-driver.js +297 -0
  39. package/dist/runner/argent.d.ts +349 -0
  40. package/dist/runner/argent.js +1211 -0
  41. package/dist/runner/check-plan.d.ts +45 -0
  42. package/dist/runner/check-plan.js +210 -0
  43. package/dist/runner/cli.d.ts +20 -0
  44. package/dist/runner/cli.js +23 -0
  45. package/dist/runner/compare-latest.d.ts +99 -0
  46. package/dist/runner/compare-latest.js +233 -0
  47. package/dist/runner/compare.d.ts +58 -0
  48. package/dist/runner/compare.js +157 -0
  49. package/dist/runner/demo-loop.d.ts +45 -0
  50. package/dist/runner/demo-loop.js +170 -0
  51. package/dist/runner/example-android-live.d.ts +137 -0
  52. package/dist/runner/example-android-live.js +454 -0
  53. package/dist/runner/example-ios-live.d.ts +137 -0
  54. package/dist/runner/example-ios-live.js +471 -0
  55. package/dist/runner/host-doctor.d.ts +131 -0
  56. package/dist/runner/host-doctor.js +628 -0
  57. package/dist/runner/init-project.d.ts +88 -0
  58. package/dist/runner/init-project.js +263 -0
  59. package/dist/runner/ios-simctl-driver.d.ts +69 -0
  60. package/dist/runner/ios-simctl-driver.js +97 -0
  61. package/dist/runner/ios-simctl.d.ts +254 -0
  62. package/dist/runner/ios-simctl.js +1415 -0
  63. package/dist/runner/live-android.d.ts +137 -0
  64. package/dist/runner/live-android.js +539 -0
  65. package/dist/runner/live-comparison.d.ts +67 -0
  66. package/dist/runner/live-comparison.js +147 -0
  67. package/dist/runner/live-ios.d.ts +137 -0
  68. package/dist/runner/live-ios.js +460 -0
  69. package/dist/runner/live-proof-summary.d.ts +263 -0
  70. package/dist/runner/live-proof-summary.js +465 -0
  71. package/dist/runner/live-proof.d.ts +467 -0
  72. package/dist/runner/live-proof.js +920 -0
  73. package/dist/runner/local-env.d.ts +64 -0
  74. package/dist/runner/local-env.js +155 -0
  75. package/dist/runner/profile-android.d.ts +82 -0
  76. package/dist/runner/profile-android.js +671 -0
  77. package/dist/runner/profile-ios.d.ts +108 -0
  78. package/dist/runner/profile-ios.js +532 -0
  79. package/dist/runner/profile-mobile.d.ts +254 -0
  80. package/dist/runner/profile-mobile.js +1307 -0
  81. package/dist/runner/validate-project.d.ts +273 -0
  82. package/dist/runner/validate-project.js +1501 -0
  83. package/docs/adapters.md +145 -0
  84. package/docs/api.md +94 -0
  85. package/docs/authoring.md +196 -0
  86. package/docs/concepts.md +136 -0
  87. package/docs/consumer-rehearsal.md +115 -0
  88. package/docs/contracts.md +267 -0
  89. package/docs/live-proofs.md +270 -0
  90. package/docs/principles.md +46 -0
  91. package/examples/event-logs/app-startup-baseline.log +4 -0
  92. package/examples/event-logs/app-startup-current.log +4 -0
  93. package/examples/minimal-app/README.md +70 -0
  94. package/examples/mobile-app/README.md +302 -0
  95. package/examples/mobile-app/app.json +22 -0
  96. package/examples/mobile-app/asl/package-scripts.json +32 -0
  97. package/examples/mobile-app/asl.config.json +37 -0
  98. package/examples/mobile-app/event-logs/android-app-startup.log +4 -0
  99. package/examples/mobile-app/event-logs/android-open-close-cycle.log +12 -0
  100. package/examples/mobile-app/event-logs/android-scroll-settle.log +12 -0
  101. package/examples/mobile-app/event-logs/app-startup.log +4 -0
  102. package/examples/mobile-app/event-logs/open-close-cycle.log +12 -0
  103. package/examples/mobile-app/event-logs/scroll-settle.log +12 -0
  104. package/examples/mobile-app/index.ts +20 -0
  105. package/examples/mobile-app/metro.config.js +20 -0
  106. package/examples/mobile-app/package.json +62 -0
  107. package/examples/mobile-app/patches/expo-modules-jsi@56.0.10.patch +19 -0
  108. package/examples/mobile-app/plugins/with-ios-build-compat.js +271 -0
  109. package/examples/mobile-app/pnpm-lock.yaml +4440 -0
  110. package/examples/mobile-app/runner-manifests/evidence-provider.json +79 -0
  111. package/examples/mobile-app/runner-manifests/primary-runner.json +19 -0
  112. package/examples/mobile-app/scenarios/android/app-startup-video.json +73 -0
  113. package/examples/mobile-app/scenarios/android/app-startup.json +44 -0
  114. package/examples/mobile-app/scenarios/android/open-close-cycle.json +54 -0
  115. package/examples/mobile-app/scenarios/android/scroll-settle.json +49 -0
  116. package/examples/mobile-app/scenarios/ios/app-startup.json +44 -0
  117. package/examples/mobile-app/scenarios/ios/open-close-cycle.json +54 -0
  118. package/examples/mobile-app/scenarios/ios/scroll-settle.json +49 -0
  119. package/examples/mobile-app/scenarios/mobile/app-startup.json +91 -0
  120. package/examples/mobile-app/scenarios/mobile/open-close-cycle.json +160 -0
  121. package/examples/mobile-app/scenarios/mobile/scroll-settle.json +148 -0
  122. package/examples/mobile-app/scripts/asl-capture-accessibility-provider.mjs +112 -0
  123. package/examples/mobile-app/scripts/asl-capture-profiler-provider.mjs +127 -0
  124. package/examples/mobile-app/src/devtools/profile-session.ts +7 -0
  125. package/examples/mobile-app/src/example-screen.tsx +322 -0
  126. package/examples/mobile-app/tsconfig.json +16 -0
  127. package/examples/mobile-app/tsconfig.typecheck.json +13 -0
  128. package/examples/runners/README.md +44 -0
  129. package/examples/runners/adb-android.json +25 -0
  130. package/examples/runners/agent-device-android.json +27 -0
  131. package/examples/runners/agent-device-ios.json +27 -0
  132. package/examples/runners/argent-android.json +32 -0
  133. package/examples/runners/argent-ios.json +32 -0
  134. package/examples/runners/argent-react-profiler-provider.json +15 -0
  135. package/examples/runners/axe-accessibility-provider.json +24 -0
  136. package/examples/runners/manual-log-ingest.json +9 -0
  137. package/examples/runners/rozenite-profiler-provider.json +9 -0
  138. package/examples/runners/script-accessibility-provider.json +24 -0
  139. package/examples/runners/script-memory-provider.json +24 -0
  140. package/examples/runners/script-network-provider.json +24 -0
  141. package/examples/runners/script-profiler-provider.json +30 -0
  142. package/examples/runners/xcodebuildmcp-ios.json +29 -0
  143. package/examples/scenarios/ios/app-startup.json +28 -0
  144. package/examples/scenarios/ios/open-close-cycle.json +35 -0
  145. package/examples/scenarios/mobile/app-startup.json +72 -0
  146. package/examples/scenarios/mobile/media-open-close.json +141 -0
  147. package/examples/scenarios/mobile/open-close-cycle.json +135 -0
  148. package/examples/scenarios/mobile/scroll-settle.json +106 -0
  149. package/package.json +240 -0
  150. package/schemas/budget-verdict.schema.json +115 -0
  151. package/schemas/causal-run.schema.json +279 -0
  152. package/schemas/comparison.schema.json +196 -0
  153. package/schemas/health.schema.json +108 -0
  154. package/schemas/live-proof-set.schema.json +195 -0
  155. package/schemas/live-proof.schema.json +413 -0
  156. package/schemas/manifest.schema.json +204 -0
  157. package/schemas/metrics.schema.json +137 -0
  158. package/schemas/project-validation.schema.json +343 -0
  159. package/schemas/runner-capabilities.schema.json +217 -0
  160. package/schemas/scenario.schema.json +400 -0
  161. package/schemas/verdict.schema.json +88 -0
  162. package/templates/evidence-provider.json +83 -0
  163. package/templates/gitignore-snippet +9 -0
  164. package/templates/integration-readme.md +125 -0
  165. package/templates/mobile-scenario.json +133 -0
  166. package/templates/package-scripts.json +32 -0
  167. package/templates/primary-runner.json +19 -0
  168. package/templates/project.config.json +37 -0
  169. package/templates/scripts/asl-capture-accessibility-provider.mjs +112 -0
  170. package/templates/scripts/asl-capture-profiler-provider.mjs +127 -0
@@ -0,0 +1,270 @@
1
+ # Live Proofs
2
+
3
+ Use this page when you want to move from contract validation into runtime evidence.
4
+
5
+ The goal of a live proof is not just to see a command pass. The goal is to preserve scenario health, verdicts, raw evidence, metrics, summaries, and comparison context in the standard artifact layout.
6
+
7
+ ## Fixture Loop
8
+
9
+ Use the fixture loop when no simulator or device is available:
10
+
11
+ ```bash
12
+ pnpm demo:loop -- --out artifacts/demo-loop
13
+ ```
14
+
15
+ The command runs preflight, profiles baseline/current event logs, writes run artifacts, compares the current run against the latest trusted prior run, and refreshes the current run's `agent-summary.md`.
16
+
17
+ ## Host/Device Access
18
+
19
+ Keep deterministic validation and live device proof as separate execution lanes.
20
+
21
+ These commands are sandbox-safe because they use committed fixtures, generated temporary apps, package metadata, or explicit artifact files:
22
+
23
+ - `pnpm test`
24
+ - `pnpm release:check`
25
+ - `pnpm package:smoke`
26
+ - `pnpm consumer:rehearse`
27
+ - `pnpm demo:loop`
28
+ - `asl-check-plan`
29
+ - profile commands that read `--events`
30
+ - `asl-live-proof`
31
+
32
+ These commands are host/device lanes and should run with access to the local device driver state from the first attempt:
33
+
34
+ - `asl-host-doctor`
35
+ - `asl-android-adb`, `asl-profile-android --adb-capture`, and `asl-live-android`
36
+ - `asl-ios-simctl`, `asl-profile-ios --simctl-capture`, and `asl-live-ios`
37
+ - `asl-agent-device` and aggregate proofs with `--agent-device-proof`
38
+ - `asl-argent` and aggregate proofs with `--argent-proof`
39
+ - example app install/build/start commands that touch emulators, simulators, Metro, or native build tools
40
+
41
+ If a live command cannot reach adb, CoreSimulator, `agent-device`, Argent, a simulator, an emulator, or a required local app service, classify the result as runner environment health. Do not call it an app regression or a scenario failure until the platform preflight and scenario health have passed. The runners write failed health artifacts and `nextAction` values for this case so agents can preserve the evidence trail while rerunning the same command with the right host/device access.
42
+
43
+ For repeated local work, prefer narrow, reusable permissions for the exact package scripts you run often instead of one-off retries after expected preflight failures. Keep Metro on an isolated port for the proof app, use direct installed binaries when available, and keep bounded command timeouts on wrapper-based tools such as `npx`-launched Argent.
44
+
45
+ Put machine-specific runner settings in an ignored `.asl.local.env` file at the app or repo root instead of repeating inline environment variables in every command. ASL CLIs load the nearest `.asl.local.env` without overriding already-exported values, so CI and explicit shell overrides still win. Typical local values include:
46
+
47
+ ```sh
48
+ ASL_HOST_DOCTOR_REQUIRE=android,ios,agent-device,argent
49
+ ASL_AGENT_DEVICE_REQUIRED_PLATFORMS=ios,android
50
+ ASL_ANDROID_AGENT_DEVICE_SESSION=android-example
51
+ ASL_IOS_AGENT_DEVICE_SESSION=default
52
+ ASL_ARGENT_BIN=pnpm
53
+ ASL_ARGENT_BASE_ARGS="dlx @swmansion/argent run"
54
+ ASL_ARGENT_IOS_SIMCTL_SCREENSHOT_FALLBACK=1
55
+ ```
56
+
57
+ Before a live proof, run the host doctor for the lanes you intend to use:
58
+
59
+ ```bash
60
+ asl-host-doctor --require android,ios --out artifacts/asl/host-doctor
61
+
62
+ ASL_ARGENT_BIN=pnpm \
63
+ ASL_ARGENT_BASE_ARGS="dlx @swmansion/argent run" \
64
+ asl-host-doctor \
65
+ --require android,ios,agent-device,argent \
66
+ --agent-device-require-platforms ios,android \
67
+ --out artifacts/asl/host-doctor
68
+ ```
69
+
70
+ The doctor composes the existing adb, simctl, agent-device, and Argent checks into one ASL artifact set. A failed doctor is environment evidence, not product evidence: fix the host access or command shape before starting scenario execution.
71
+
72
+ ## Generic Mobile Proof
73
+
74
+ Use the generic live runners in a consuming app after `asl-init` has created `asl.config.json`, `scenarios/mobile/<id>.json`, and the `asl:*` package-script snippets:
75
+
76
+ ```bash
77
+ asl-live-android \
78
+ --config asl.config.json \
79
+ --scenario scenarios/mobile/app-startup.json \
80
+ --package dev.example.app \
81
+ --serial <emulator-serial> \
82
+ --out artifacts/asl/android-live \
83
+ --compare-latest \
84
+ --fail-on-regression
85
+
86
+ asl-live-ios \
87
+ --config asl.config.json \
88
+ --scenario scenarios/mobile/app-startup.json \
89
+ --bundle dev.example.app \
90
+ --device <simulator-udid> \
91
+ --out artifacts/asl/ios-live \
92
+ --compare-latest \
93
+ --fail-on-regression
94
+ ```
95
+
96
+ These commands run one portable scenario through the platform preflight, profile-session capture, profile artifact pipeline, optional sidecar interaction runners, optional latest-trusted comparison, and aggregate live-proof writer. The platform profile runner captures app-owned truth first; sidecars run afterward so a UI-driver session cannot interfere with the evidence-producing adb or simctl window.
97
+ When no trusted prior run exists, the comparison is recorded as skipped without failing the live proof. When a comparable prior run exists, `--fail-on-regression` makes a regression exit nonzero after artifacts are written.
98
+
99
+ Add sidecars when external drivers are available:
100
+
101
+ ```bash
102
+ ASL_ARGENT_BIN=/path/to/argent \
103
+ asl-live-android --config asl.config.json --scenario scenarios/mobile/app-startup.json \
104
+ --package dev.example.app --serial <emulator-serial> --out artifacts/asl/android-live \
105
+ --agent-device-proof --argent-proof --compare-latest --fail-on-regression
106
+
107
+ ASL_ARGENT_BIN=/path/to/argent \
108
+ asl-live-ios --config asl.config.json --scenario scenarios/mobile/app-startup.json \
109
+ --bundle dev.example.app --device <simulator-udid> --out artifacts/asl/ios-live \
110
+ --agent-device-proof --argent-proof --compare-latest --fail-on-regression
111
+ ```
112
+
113
+ The platform runner still owns profile evidence. `agent-device` and Argent contribute interaction proof pointers under the same aggregate `live-proof.json` only after the profile run has produced trusted artifacts. If the profile health or budget verdict fails, requested sidecars are recorded under `skippedInteractionProofs` with a recovery hint, and the aggregate command exits nonzero after writing `live-proof.json`. If a sidecar itself fails a required step, the aggregate command also fails after preserving that sidecar's raw output and `agent-summary.md`. Optional sidecar failures, such as a screenshot helper failing after a successful UI assertion, are preserved as interaction proof warnings so agents can report partial evidence without treating timing as suspect.
114
+
115
+ ## Android Proof
116
+
117
+ With the neutral Expo example app installed on an online Android emulator or device, run:
118
+
119
+ ```bash
120
+ pnpm example:app:android
121
+ pnpm example:android:live
122
+ ```
123
+
124
+ The aggregate proof runs adb/package preflight plus the canonical startup, open-close, and scroll-settle scenarios. It writes a batch entrypoint under:
125
+
126
+ ```text
127
+ artifacts/example-mobile-app/android/_live-proof/android-live-proof/agent-summary.md
128
+ ```
129
+
130
+ The root example live scripts pass `--compare-latest --fail-on-regression` by default. Missing same-lane baselines are recorded as skipped comparison evidence; real regressions exit nonzero after artifacts are written. Use a run suffix when preserving before/after runs:
131
+
132
+ ```bash
133
+ pnpm example:android:live -- --run-suffix before-change
134
+ pnpm example:android:live -- --run-suffix after-change
135
+ ```
136
+
137
+ Read [Example Mobile App: Android Capture](../examples/mobile-app/README.md#android-capture) for Metro routing, adb permissions, individual scenario commands, selector behavior, and optional video capture.
138
+
139
+ Expo dev-client Android shells may need an explicit Metro deep link after the native app launches. Put that local URL in ignored env state, for example `ASL_EXAMPLE_ANDROID_DEV_CLIENT_URL=asl-example://expo-development-client/?url=http%3A%2F%2F10.0.2.2%3A8097`, so Android profile capture opens the correct app session before profile-session deep links. When bundle load time is variable, also set `ASL_EXAMPLE_ANDROID_DEV_CLIENT_READY_PATTERN='Running "main"'` so the runner waits for bounded logcat readiness evidence before sending scenario links.
140
+
141
+ Apps using the ASL profile-session AsyncStorage bridge can opt into storage delivery with `--android-profile-session-storage`. The Android runner resolves the session `startedAt` from the selected device clock before writing AsyncStorage, so milestone timing stays device-relative instead of host-clock-relative. Override the default storage keys with `ASL_ANDROID_PROFILE_SESSION_STORAGE_KEY` and `ASL_ANDROID_PROFILE_COMMAND_STORAGE_KEY` only when adopting an existing app-owned bridge.
142
+
143
+ ## iOS Proof
144
+
145
+ With the neutral Expo example app installed on a booted iOS simulator and Metro connected, run:
146
+
147
+ ```bash
148
+ pnpm example:app:ios:prebuild
149
+ pnpm example:app:start:isolated
150
+ pnpm example:app:ios
151
+ pnpm example:ios:live
152
+ ```
153
+
154
+ The aggregate proof runs simctl preflight plus the canonical startup, open-close, and scroll-settle scenarios. It writes a batch entrypoint under:
155
+
156
+ ```text
157
+ artifacts/example-mobile-app/ios/_live-proof/ios-live-proof/agent-summary.md
158
+ ```
159
+
160
+ The root example live scripts pass `--compare-latest --fail-on-regression` by default. Use a run suffix the same way:
161
+
162
+ ```bash
163
+ pnpm example:ios:live -- --run-suffix after-change
164
+ ```
165
+
166
+ Expo dev-client iOS shells may need an explicit Metro deep link after the native app launches. Put that local URL in ignored env state, for example `ASL_EXAMPLE_IOS_DEV_CLIENT_URL=asl-example://expo-development-client/?url=http%3A%2F%2Flocalhost%3A8097`, so iOS profile capture opens the correct app session before collecting evidence.
167
+
168
+ The default iOS live proof transport seeds profile-session control into simulator app storage. Use `--ios-profile-session-transport deeplink` when the app should receive profile-session start and command control through app URLs instead.
169
+
170
+ When an iOS app exits during the capture window, inspect `raw/ios-app-lifecycle-log.txt` first. If the host wrote a matching DiagnosticReports crash file in time, ASL also attaches it as `raw/ios-host-diagnostic-report-<bundle>.ips` and records the bounded search in `raw/ios-host-diagnostic-report-search.txt`.
171
+
172
+ Read [Example Mobile App: iOS Capture](../examples/mobile-app/README.md#ios-capture) for prebuild, Xcode selection, simulator permissions, stored profile events, and individual scenario commands.
173
+
174
+ ## Sidecar Interaction Proof
175
+
176
+ When `agent-device` or Argent is available, the example aggregate proofs can attach interaction sidecars:
177
+
178
+ ```bash
179
+ ASL_AGENT_DEVICE_REQUIRED_PLATFORMS=ios,android pnpm agent-device:check
180
+ ASL_ARGENT_BIN=/path/to/argent pnpm argent:check
181
+ ASL_EXAMPLE_ANDROID_AGENT_DEVICE_SESSION=<name> pnpm example:android:live:agent-device -- --run-suffix after-change
182
+ ASL_EXAMPLE_IOS_AGENT_DEVICE_SESSION=<name> pnpm example:ios:live:agent-device -- --run-suffix after-change
183
+ pnpm example:android:live:argent -- --run-suffix after-change
184
+ pnpm example:ios:live:argent -- --run-suffix after-change
185
+ ```
186
+
187
+ The `agent-device:check` and `argent:check` scripts pass `--out` and write availability `health.json`, `verdict.json`, `agent-summary.md`, and raw tool-surface JSON under `artifacts/agent-device-check` and `artifacts/argent-check`.
188
+
189
+ Use the combined runner scripts when you want every configured sidecar to contribute to the same aggregate proof:
190
+
191
+ ```bash
192
+ ASL_EXAMPLE_ANDROID_AGENT_DEVICE_SESSION=<name> pnpm example:android:live:runners -- --run-suffix after-change
193
+ ASL_EXAMPLE_IOS_AGENT_DEVICE_SESSION=<name> pnpm example:ios:live:runners -- --run-suffix after-change
194
+ ```
195
+
196
+ Run `pnpm agent-device:check` before using agent-device sidecars; set `ASL_AGENT_DEVICE_REQUIRED_PLATFORMS=ios,android` when the local proof must confirm both booted OS targets. The check runs `agent-device session list --json`, writes active sessions into `raw/agent-device-availability.json`, and includes a compact `agent_device_sessions` line in `agent-summary.md`. If the artifact shows a named session already owns the target device, pass `ASL_EXAMPLE_ANDROID_AGENT_DEVICE_SESSION` or `ASL_EXAMPLE_IOS_AGENT_DEVICE_SESSION` to the aggregate script, or pass `--agent-device-session <name>` directly after `--`. This defaults to `reuse`, where the session owns target selection. Set `ASL_EXAMPLE_ANDROID_AGENT_DEVICE_SESSION_MODE=bind` or `ASL_EXAMPLE_IOS_AGENT_DEVICE_SESSION_MODE=bind` when you want ASL to create or name the sidecar session while still forwarding the configured Android serial or iOS UDID; this avoids borrowing a default session that is bound to the wrong OS. For Argent, prefer a real `argent` executable on PATH, or set `ASL_ARGENT_BIN=/path/to/argent` when the package manager installed it somewhere else. `ASL_ARGENT_BIN=npx` with `ASL_ARGENT_BASE_ARGS="--yes @swmansion/argent run"` is supported as a wrapper shape, but run `pnpm argent:check` before relying on it because package-manager wrappers can be slower than direct binaries. Run `pnpm argent:check` first when you need a bounded tool-surface proof before attaching Argent to a device scenario. Both checks preserve artifacts via `--out`, so failed command-surface evidence can be inspected without relying on terminal scrollback. Direct iOS `asl-argent` runs can set `ASL_ARGENT_IOS_SIMCTL_SCREENSHOT_FALLBACK=1` so simctl supplies screenshot evidence when Argent can launch and inspect the app but its iOS screenshot backend is unavailable. The platform runner still owns adb or simctl preflight and profile evidence, and sidecars run only after that profile evidence has passed health and budget gates. Each executed sidecar contributes interaction proof, captures, and warning summaries into the same aggregate artifact graph; skipped sidecars remain visible in the aggregate proof so agents know which runner evidence is missing and why.
197
+
198
+ ## Platform Set Gate
199
+
200
+ After Android and iOS live proofs have both written aggregate artifacts, assert the platform set with one inspector command:
201
+
202
+ ```bash
203
+ pnpm example:mobile:live-proof
204
+ ```
205
+
206
+ For a consumer app scaffolded with `asl-init`, the equivalent script is:
207
+
208
+ ```bash
209
+ pnpm asl:live-proof:both
210
+ ```
211
+
212
+ Both commands call `asl-live-proof` with two `--file` values, `--require-platforms android,ios`, `--out`, and `--fail-on-regression`. The gate writes `live-proof-set.json` and `agent-summary.md` under the proof-set artifact directory, then exits nonzero when a required platform proof is missing, when any proof artifact has `status: failed`, or when a required regression gate reports `comparisonStatus: regressed`. Use `ASL_ANDROID_LIVE_PROOF` and `ASL_IOS_LIVE_PROOF` in consumer apps, or `ASL_EXAMPLE_ANDROID_LIVE_PROOF` and `ASL_EXAMPLE_IOS_LIVE_PROOF` in the checked-in example app, to point at suffixed proof files.
213
+
214
+ For a final local proof before an agent claims improvement, enable artifact pointer checks:
215
+
216
+ ```bash
217
+ ASL_REQUIRE_LIVE_PROOF_ARTIFACTS=1 pnpm example:mobile:live-proof
218
+ ASL_REQUIRE_LIVE_PROOF_ARTIFACTS=1 pnpm asl:live-proof:both
219
+ ```
220
+
221
+ This passes `--require-artifacts` so `asl-live-proof` verifies that each referenced run directory, summary, comparison artifact, and interaction capture exists on disk. Leave it off when inspecting copied or archived `live-proof.json` files without the full artifact tree.
222
+
223
+ By default, relative pointers are resolved from the current working directory. Use `--artifact-base-dir <dir>` with direct `asl-live-proof` calls when inspecting a project from a different shell location.
224
+
225
+ ## Comparison
226
+
227
+ Compare explicit completed runs:
228
+
229
+ ```bash
230
+ pnpm compare \
231
+ -- --baseline artifacts/runs/app-startup/baseline \
232
+ --current artifacts/runs/app-startup/current \
233
+ --out artifacts/runs/app-startup/current \
234
+ --fail-on-regression
235
+ ```
236
+
237
+ Or compare the current run against the newest trusted prior run for the same scenario:
238
+
239
+ ```bash
240
+ pnpm compare:latest \
241
+ -- --root artifacts/runs \
242
+ --scenario app-startup \
243
+ --current artifacts/runs/app-startup/current \
244
+ --out artifacts/runs/app-startup/current \
245
+ --fail-on-regression
246
+ ```
247
+
248
+ Scenario health must pass before timing or budget evidence can support an improvement or regression claim.
249
+
250
+ ## Release Gate
251
+
252
+ Before publishing, run:
253
+
254
+ ```bash
255
+ pnpm release:check
256
+ ```
257
+
258
+ That gate runs tests, readiness checks, package smoke, installed-binary checks, fake-device example proofs, schema/example/template/doc packaging checks, and the packed-package consumer rehearsal.
259
+
260
+ Package smoke and consumer rehearsal keep child commands bounded so package-manager stalls fail with the temporary rehearsal directory preserved. Set `ASL_PACKAGE_GATE_TIMEOUT_MS` to raise the per-command timeout when a local registry, proxy, or cold package cache is slow:
261
+
262
+ ```bash
263
+ ASL_PACKAGE_GATE_TIMEOUT_MS=300000 pnpm release:check
264
+ ```
265
+
266
+ Read next:
267
+
268
+ - [Contracts](contracts.md) for artifact layout and supported runner surface
269
+ - [Consumer App Rehearsal](consumer-rehearsal.md) for adoption inside an existing app
270
+ - [examples/mobile-app](../examples/mobile-app/README.md) for detailed dogfood app commands
@@ -0,0 +1,46 @@
1
+ # Principles
2
+
3
+ `agent-scenario-loop` is a scenario orchestration and evidence collection layer for agent-driven software development.
4
+
5
+ Read this after [Concepts](concepts.md) if you want the project doctrine in a compact form.
6
+
7
+ The durable value is not any one runner. The durable value is a stable scenario and evidence contract that survives runner changes.
8
+
9
+ It is not another agent runner. It is the layer that coordinates runners, preserves evidence, and keeps scenarios useful as tooling changes.
10
+
11
+ Scenarios are long-lived project assets. They describe important application behaviors, not the temporary mechanics of the current runner.
12
+
13
+ ## Four planes
14
+
15
+ 1. Control plane
16
+ Use semantic app commands, deep links, and deterministic hooks before falling back to raw UI replay.
17
+
18
+ 2. Truth plane
19
+ Use explicit profile events, stored signals, route state, and committed artifacts as the source of truth.
20
+
21
+ 3. Evidence plane
22
+ Preserve logs, screenshots, videos, profiler exports, memory captures, network captures, UI trees, metrics, and verdicts in one stable artifact layout.
23
+
24
+ 4. Realism plane
25
+ Use taps, swipes, and full UI interaction for realism checks and last-mile validation, not as the primary control architecture.
26
+
27
+ ## Invariants
28
+
29
+ - Deterministic evidence beats quick scenario passability.
30
+ - Scenario health is part of product truth. A flaky scenario is not trustworthy evidence.
31
+ - Generated runs are outputs, not source.
32
+ - The artifact contract is a public API.
33
+ - App integration stays thin.
34
+ - Runners and interaction drivers are adapters, not schema owners. Scenarios and artifacts must outlive any individual runner.
35
+ - Runners can be swapped, combined, introduced, or compared without rewriting scenario definitions.
36
+ - The application behavior remains the locus of control. Tooling orbits the scenario; the scenario does not belong to the tooling.
37
+ - Every scenario execution should make future comparison easier by adding evidence and historical context.
38
+ - Failed or partial scenario health cannot support an optimization claim.
39
+ - Product-specific selectors, routes, auth assumptions, and domain events stay outside the orchestration core.
40
+ - Public claims stay narrower than internal ambition.
41
+
42
+ ## Read next
43
+
44
+ - [Contracts](contracts.md) for the current artifact and package surface
45
+ - [Runner docs](../runner/README.md) for the host execution boundary
46
+ - [README](../README.md) for the project entrypoint
@@ -0,0 +1,4 @@
1
+ 2026-01-01T00:00:00.000Z demo [profile-event] {"event":"surface_open_requested","scenario":"app-startup","runId":"demo-baseline","iteration":1,"atMs":0}
2
+ 2026-01-01T00:00:01.800Z demo [profile-event] {"event":"app_first_usable_screen","scenario":"app-startup","runId":"demo-baseline","iteration":1,"atMs":1800}
3
+ 2026-01-01T00:00:02.000Z demo [profile-event] {"event":"surface_close_requested","scenario":"app-startup","runId":"demo-baseline","iteration":1,"atMs":2000}
4
+ 2026-01-01T00:00:02.400Z demo [profile-event] {"event":"surface_dismissed","scenario":"app-startup","runId":"demo-baseline","iteration":1,"atMs":2400}
@@ -0,0 +1,4 @@
1
+ 2026-01-01T00:01:00.000Z demo [profile-event] {"event":"surface_open_requested","scenario":"app-startup","runId":"demo-current","iteration":1,"atMs":0}
2
+ 2026-01-01T00:01:01.200Z demo [profile-event] {"event":"app_first_usable_screen","scenario":"app-startup","runId":"demo-current","iteration":1,"atMs":1200}
3
+ 2026-01-01T00:01:01.400Z demo [profile-event] {"event":"surface_close_requested","scenario":"app-startup","runId":"demo-current","iteration":1,"atMs":1400}
4
+ 2026-01-01T00:01:01.600Z demo [profile-event] {"event":"surface_dismissed","scenario":"app-startup","runId":"demo-current","iteration":1,"atMs":1600}
@@ -0,0 +1,70 @@
1
+ # Minimal App Integration
2
+
3
+ This example is intentionally documentation-only: the app integration contract is one file, `../../app/profile-session.ts`. Copy it into your app and wire it as shown below.
4
+
5
+ ## Startup wiring
6
+
7
+ Call `useProfileSessionBootstrap()` once near the app root:
8
+
9
+ ```tsx
10
+ import { useProfileSessionBootstrap } from '../../app/profile-session';
11
+
12
+ export function AppShell() {
13
+ useProfileSessionBootstrap();
14
+
15
+ return <RootNavigator />;
16
+ }
17
+ ```
18
+
19
+ ## Emitting truth events
20
+
21
+ Emit stable events around a real user journey:
22
+
23
+ ```ts
24
+ import { emitProfileEvent, storeProfileSignal } from '../../app/profile-session';
25
+
26
+ export function onComposerOpened() {
27
+ emitProfileEvent('composer_open_requested', {
28
+ flowId: 'composer-open-close',
29
+ phase: 'intent',
30
+ owner: 'composer',
31
+ });
32
+ }
33
+
34
+ export function onComposerVisible() {
35
+ emitProfileEvent('composer_opened', {
36
+ flowId: 'composer-open-close',
37
+ phase: 'visual',
38
+ owner: 'composer',
39
+ });
40
+ }
41
+
42
+ export function persistQuerySnapshot(snapshot: unknown) {
43
+ storeProfileSignal('network', 'composer-query-snapshot', snapshot, {
44
+ flowId: 'composer-open-close',
45
+ owner: 'composer',
46
+ });
47
+ }
48
+ ```
49
+
50
+ ## Deep-link control
51
+
52
+ Deep links are the control plane: the runner starts, commands, and stops profile sessions through URLs instead of replaying raw UI input. The app should respond to URLs shaped like:
53
+
54
+ - `example-app://profile-session/start?scenario=open-close-cycle&runId=run-123`
55
+ - `example-app://profile-session/command?scenario=open-close-cycle&runId=run-123&command=activate-target:composer-open-button`
56
+ - `example-app://profile-session/stop`
57
+
58
+ ## Command targets
59
+
60
+ For runner-owned flows, register stable command targets near the component that owns the behavior:
61
+
62
+ ```ts
63
+ import { registerProfileCommandTargetHandler } from '../../app/profile-session';
64
+
65
+ export function wireComposerProfileTargets(openComposer: () => void) {
66
+ return registerProfileCommandTargetHandler('composer-open-button', openComposer);
67
+ }
68
+ ```
69
+
70
+ The matching scenario command is `activate-target:composer-open-button`. The target name is the portable contract; the consuming app decides how to perform the action.