# The Verify agent

Learn how the Verify agent plans and runs browser journeys. Understand queued runs, concurrency, personas, recorded evidence, and pass or fail verdicts.

## Follow one run

The Verify agent runs one selected scenario as its assigned persona. It observes the page, takes permitted browser actions within its budget, and reports what happened. It does not edit your source code or run in a checkout.

1. **Prepare:** Verify saves a snapshot of the selected project Scenario versions, personas, target, policy, and runner image. PR requests use changed files and available diff sections to choose relevant saved Scenarios. Manual runs use your selected Scenarios.
2. **Dispatch:** Composal creates one ScenarioRun per selected Scenario and starts independent journeys in parallel within the Run's concurrency and organization limits. Prerequisites and shared-account locks can delay individual journeys.
3. **Execute:** Roder coordinates each hosted attempt and starts its pinned browser sandbox on **Blaxel**. The agent works through the scenario using browser observations and the permitted actions. Each attempt has a duration and tool budget.
4. **Evaluate:** Typed checks determine assertion outcomes. Verify aggregates the attempts, performs configured cleanup, and publishes the run result and evidence.

The model helps navigate a dynamic interface. A recorded pass requires the authored checks to succeed; the model's explanation alone is insufficient. Each run records the environment, scenario version, and runner that produced its evidence.

## Recover an unfinished scenario

In a browser scenario, the agent can recover from a missing
menu, a different layout, an offscreen control, or a stale observation in the
current browser. It inspects fresh page and screenshot evidence, tries an observed
alternative within its recovery budget, and checks the resulting application state
before completing the original step. Selecting a layout or successfully clicking
a control does not by itself establish that the intended change happened.

Recovery preserves completed steps and writes. It keeps every original outcome;
unchecked outcomes remain incomplete, and observed failures remain visible. The
run's evidence records the unmet requirement, obstacle, recovery actions and their
observed effects. If recovery runs out, it records what remains untested.

A missing teammate, an explicit access restriction, or authentication that needs
your intervention can still block a scenario. One granted account cannot stand in
for a second person. For timing-sensitive queue tests, the reply must still be
running and the intended message must still be queued when the action happens.
A drained queue does not establish successful queue management; recreating its
setup requires permission in the original scenario and must preserve prior work.

## Use a cloud passkey or app session

You can also choose **Sign In With a Browser** when adding or editing an account. Enter the app login URL, open the private browser, and sign in yourself. Return to Composal, confirm the correct test account, and select **Save Browser Session** before the displayed expiry time. The app’s cookies and storage are encrypted; the login browser closes after capture.

If the app cannot load in the private browser, check its address and select **Go** to retry. The browser stays open until its expiry time so you can complete sign-in after the app recovers.

You can refresh the live login viewer without losing the private browser or its sign-in progress. Its access stays in that viewer tab until the session expires or you save or cancel it.

Saved test accounts support **Cloud Passkey** and **App Session** authentication. To add cookies, choose **Session Cookies** when adding an account. Paste `name=value` or `name:"value"` cookies, one per line or as a Cookie header, then enter an account name and the app URL. You can leave the separate username field blank. To import a private JSON session artifact, choose **Upload File Instead**. For a passkey enrollment file, choose **Passkey** under **Other Sign-in Methods**.

Composal preserves pasted cookie values without URL decoding, scopes them to the app host, and installs them before navigation in the orchestrator and each exploration browser. The import expires after 24 hours. Refresh it sooner if the app expires or revokes the session. Composal encrypts the import and returns only its origin, expiry, and credential references. Testers receive the credential through their private browser supervisor. The model cannot read it or type it into a page.

A cloud passkey is a software authenticator registered explicitly by the account owner. The tester can use it to sign in on its enrolled origin; it cannot enroll additional passkeys. Provider acceptance must be tested. Google may reject an automated browser before asking for any password, code or passkey, so adding a passkey does not guarantee access.

Save an **App Session** from an existing Chrome login, or complete login and MFA in a temporary cloud browser:

```sh
com verify browser-session --org <org> --project <project> --account <account-id> --url https://your-app.example --chrome-profile Default
com verify browser-session --org <org> --project <project> --url https://your-app.example/login --login
```

Chrome import reads the selected app's cookies, local storage and IndexedDB. Close Chrome before copying its storage; on macOS, allow Chrome Safe Storage access when Keychain prompts. Use `--cdp http://127.0.0.1:9222` for an already signed-in local debugging profile on other platforms. Chrome 136 and later require a separate debugging data directory.

With `--login`, omit `--account` to create your first credential. Its name defaults to the app hostname followed by “browser session”; use `--name "Test admin"` to choose a name. To refresh an existing credential, pass `--account <account-id>` instead. The new credential becomes configured after you save the signed-in session.

The cloud command opens an interactive viewer for you to complete login and MFA. Return to the app, confirm the expected test account, then press Enter to save. Its private viewer link expires after 15 minutes. For separate commands, use `--login --json --no-open`, followed by `--save <browser-session-id> --confirm-account`; `--status` and `--cancel` inspect or close it. Only its creator, who must be an organization administrator, can save it.

Click the live browser screen to type, paste, or use keyboard navigation. The viewer streams changes as they happen and retains your browser session when you refresh it. If input is interrupted, check the app field before continuing; uncertain input is not replayed automatically.

Saved state contains only the selected app origin and expires after 24 hours by default. Google provider cookies and other sites are excluded. Testers restore it into their own isolated browsers. Sessions bound to a device or network may reject this transfer; if the app requires login again, refresh the session. Saving an account does not establish authenticated coverage. These commands require a compatible API, CLI and browser runner release.

Browser artifacts apply to discovery, exploration, and scenario runs. Each run gets its own browser with the saved session or passkey installed, so the login step is already done. A saved session works only on the address it was saved for. Verify refuses a run against another address before it starts; save a separate session for a pull request preview or any other address.

Choose concurrency **one** for a cloud passkey account: additional active testers receive `passkey_account_busy`. Scenario runs on that account sign in one at a time. After the first sign-in, the others start from a copy of its app session instead of waiting. App sessions support concurrent testers with separate contexts.

Shared retained-persona browsers do not install these artifacts. Artifacts expire within 30 days. Disabling an account stops future credential grants without signing out provider sessions already issued.

## Run project YAML without the dashboard

A project owns its saved YAML Scenarios, Personas, Credentials and Environments.
Each run saves a snapshot of the selected definitions and creates one ScenarioRun per scenario.
Independent scenarios execute in parallel within organization limits. Shared account
and TOTP locks queue conflicting journeys; adding concurrency does not create accounts.

```sh
com verify scenarios download --org acme --project storefront --dir scenarios
com verify scenarios lint scenarios
com verify scenarios upload --dir scenarios --dry-run --json
com verify scenarios upload --dir scenarios --json
com verify scenarios run scenarios/home.yaml scenarios/profile.yaml --org acme --project storefront --environment Preview --wait --json
com verify runs list --org acme --project storefront --json
com verify runs get <run-id> --org acme --project storefront --json
```

Download includes `project.yaml` for upload context. Upload validates all files and
saves them atomically; lint checks the bundled schema offline. Run executes the files
as written without saving them. The dashboard can run selected saved scenarios.
YAML version 1 uses one Persona and prose steps/outcomes. Version 2 declares named
actors, their Personas, and evidence ownership. Every actor must be available in the
same project. A requirement for a distinct teammate needs a distinct working account.

For a PR, enable the project's **PR Testing** settings and choose its repository,
environment template and preview source. Verify reads the current source diff,
selects relevant saved scenarios with recorded reasons, prepares one grouped run
on an exact-commit preview, and publishes its results. Low-confidence scenarios remain
explicitly untested. A missing match is not a passing browser result. Manual selection
can run other saved scenarios from the PR page.

```sh
com verify pull-requests run 45 --org acme --repo storefront --head-sha <commit-sha> --idempotency-key <stable-key> --json
com verify pull-requests get <request-id> --org acme --json
```

The PR report links the grouped run and records each scenario's result and findings.
Cleanup is reported separately: cleanup trouble does not change a passed product
verdict into a failed product verdict. Failed assertions, missing prerequisites and
untested requirements remain visible. Retrying an uncertain request uses the same
idempotency key; deliberately rerunning uses a new key.

A blocked scenario's cause identifies what needs attention. Missing test accounts
and sign-in steps that require a person are access problems. Unconfirmed outcomes
after every step completes are evidence problems attributed to Verify's runner.
Recovery limits preserve the obstacle the agent encountered; model-provider and
browser-control failures are runner problems. If an app navigation still returns
an HTTP error or cannot connect after one retry, Verify stops that scenario and
attributes the problem to the app. Other queued scenarios remain eligible to run.

## Understand queued runs and concurrency

**Queued** means Verify has accepted the run or attempt and its browser session has yet to start. Verify dispatches selected scenario agents together within the configured concurrency and can dispatch multiple runs at once. Shared setup, Roder capacity, and the requested parallelism can delay an attempt. The run page shows when a scenario is waiting for its account's sign-in turn. The concurrency limit sets the maximum: a Run with one Scenario starts one scenario agent regardless of that limit.

Once admitted, the attempt moves to **Running** and its browser preview appears in **Live** when the runner supplies one. If a run remains queued unexpectedly, inspect its **Logs** and attempt state; a failed dispatch or unavailable runner needs investigation. A queued badge by itself does not establish that Blaxel is running or that the application failed.

## Personas and credentials

Project Personas can describe anonymous users, members, moderators, and administrators. Give each scenario the persona and start state it needs. For example, an administrator can create a category, one member can start a topic, another can reply, and a moderator can review a report. Declare named actors with distinct configured credentials for journeys involving several users. The coordinator stages dependent actions between their isolated sessions; additional actors require available accounts.

Store test-account values in your project's **Credentials** and refer to their logical keys from scenarios. Verify supplies only the requested values to an admitted attempt. Prefer synthetic accounts and data, especially when the target URL is production. An external URL registration describes the target; actions still have to fit the environment's policy and the approved test scope.

## Evidence and verdicts

Use **Live** to watch one browser or **Diagnostics → Agent Grid** to watch every session in a grid that fills the viewport, with no gaps between tiles. While agents run and runners are connected, previews refresh about every two seconds. These are captured frames, not continuous video.

When an attempt finishes and its recording becomes available, the Grid tile plays the video muted on repeat. You can watch all completed recordings together. Attempts without recordings keep their captured screenshot, if available. Select a tile to inspect that attempt in Live, or open **Recordings** to revisit recorded steps.

**Findings & Results** shows the assertions. Use **Diagnostics → Logs** and browser Console and Network events to distinguish app errors from sign-in, selector, timing, or runner problems. **Artifacts** holds protected screenshots and recordings, which can include test data visible in the browser.

Agents can scroll the page and independently scrolling panels to reveal controls below the fold. Each scroll returns a fresh view of the visible content before the next interaction. New screenshots, live frames and recordings show that same browser viewport, including its scroll position. Earlier full-page screenshots remain full-page artifacts.

Treat a failed journey as a lead to investigate. An assertion failure with a captured app state supports a product finding; an agent or infrastructure failure may leave the product outcome unjudged. Use [Verify overview](/docs/verify) for the first-run path and [scenario and MCP reference](/docs/verification) for the detailed setup and recording controls.

If a hosted worker stops reporting heartbeats for three minutes, Verify detects the loss on its next maintenance tick and ends the attempt with `runner_lost`. Recorded browser events remain available, and unreported assertions stay unknown. Cleanup remains pending until the supervisor confirms it; Verify does not automatically repeat the browser journey without that cleanup confirmation. The attempt's full deadline still applies independently.
