> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reticle.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Multi agent testing

# Multi-agent & multi-project testing

Reticle is built for the messy real world: several apps running at once, ports that shift between runs, and many agents driving different flows of the same app in parallel — without each one spinning up its own Chromium. This page explains how that works and how to use it.

## The mental model

* **One daemon per machine.** `reticle mcp` discovers a running daemon (via `~/.reticle`) or starts one. A crashed daemon's stale pidfile is reclaimed automatically, so you never chase "port already in use" or a zombie server.
* **Identity is the app, not the port.** The build plugin stamps a stable `projectId` that travels in every connection. If your Next app usually runs on `:3000` but boots on `:3001` today, Reticle still knows which app it is — and an agent scoped to project A will never accidentally drive project B's tab. Origin is only a fallback hint.
* **One browser, many contexts.** When agents need their own headless tabs, the daemon's **browser pool** launches a single Chromium and hands out isolated contexts (one per flow) — cheap, and capped so a big fan-out can't exhaust the machine. Over-cap requests queue.
* **Attach-only.** Reticle never starts your dev server. It connects to an app you're already running (or opens a headless tab pointed at it).

## Manual testing — \~5 minutes

1. Add the plugin (Vite/Next) or one `reticle.connect()` call. (See [getting-started](./getting-started.md).)
2. Start your app as you normally do.
3. Open it in a browser — the in-page panel shows Reticle is connected.
4. Click around; flag anything that looks wrong with the "Flag a bug" annotator. The agent drains those with `reticle_session {action:"review"}`.

## Agent testing — \~2 minutes

With the app running and instrumented, an agent drives a flow end to end:

```text theme={null}
reticle_lease {action:"acquire"} { url: "http://localhost:3000/dashboard" }
  → { sessionId: "lease-…", ready: true, leased: 1, queued: 0 }
reticle_act    { sessionId, ... }      # drive the flow
reticle_assert { sessionId, ... }      # verify intent
reticle_lease {action:"release"} { sessionId }    # free the slot
```

`reticle_lease {action:"acquire"}` opens a fresh isolated headless context against your **already-running** app, stamps the lease identity into the URL so the app's own SDK registers under a sessionId you can target, and waits until that tab has connected (`ready: true`) before returning — so the sessionId is usable immediately. Release when the flow finishes.

## 10 agents, 10 flows, one dashboard

This is the design target, and it needs no special setup:

* Each agent calls `reticle_lease {action:"acquire"}` for the same dashboard URL → its own isolated context (own cookies/storage) in the **one** shared Chromium.
* The pool caps simultaneous contexts (`RETICLE_MAX_CONTEXTS`, default scales with CPU under a ceiling); extra acquires queue and proceed as slots free.
* Flows can't bleed into each other — contexts are isolated and every session is scoped by `projectId`.
* A single crashed page is reclaimed on its own, and if an agent crashes or hangs its lease stops being touched and the **lease reaper** reclaims the context after a TTL, freeing the slot. One dead agent never starves the others.

`reticle_sessions` lists everything with `projectId` (group by app) and `leased` (pool context vs a human tab), so an orchestrator can see the whole fleet at a glance.

## Knobs

| Env                    | Default                           | Effect                                              |
| ---------------------- | --------------------------------- | --------------------------------------------------- |
| `RETICLE_MAX_CONTEXTS` | `min(8, cpus-1)`                  | Max simultaneous leased headless contexts.          |
| `RETICLE_PORT`         | from `.reticle.json`, else `4400` | Daemon port (rarely needed — discovery handles it). |

## Why not just open many browsers?

Ten Chromiums is hundreds of MB each and will thrash a laptop. Ten contexts in one browser is a few MB apiece and fully isolated — same correctness, a fraction of the cost. That's the whole point of the pool.

**Measured** (`bench/harness/multi-agent-throughput.mjs`): 16 verification flows that take **35.4s** one-at-a-time finish in **5.2s** across 8 leased contexts on a single Chromium — **6.78× faster**, \~30s saved per batch, with all 8 contexts live at peak. The speed-up scales with agent count up to the cap; the win over launching a browser per agent grows with how much per-agent browser startup you avoid.
