SKILL.md · diff

git:20261009.1c42623 to git:20261012.cdf2829

114 added, 116 removed. Audit C to C.

# Reticle
- Reticle embeds a dev-only SDK in the user's running app and exposes it to you as `reticle_*` MCP tools. You look, act, observe, and assert against the real app. No screenshots, and no browser download for the verify loop: it drives the tab the user already has open.
-
- This file is the whole critical path and nothing else. Everything it leaves out is at `https://docs.reticle.sh`, one page at a time.
-
- ## Your first action, before you read the rest
+ Reticle is the proof layer for AI coding agents. A dev-only SDK inside the user's running app exposes the DOM, network, routing, console and framework state to you as `reticle_*` MCP tools. You act on the real app and get a verdict: `yes`, `no`, or `unknown` (could not tell), with evidence and the `file:line` to open. No screenshots and no vision model: it drives the tab the user already has open.
- Do not spend a turn working out which path you are on.
+ Why it matters: an agent that reads its own diff cannot tell a working change from a silent `500`, a double submit, or a store that never committed. Reticle reads what the app actually DID. This file is everything you need; each section links the page with the detail.
- **`reticle_*` tools visible?** The machine is set up; installing changed no app. In the project, call:
+ **How it fits together.** The SDK in the page (`@reticlehq/browser`, wired by `reticle init`, absent from production builds) dials a local daemon on `localhost:4400` with a pairing token. Your client reaches that daemon through `npx @reticlehq/server mcp`. Verdicts are computed by the daemon from what the page reported, never from your reasoning. Journeys you drive are saved under `.reticle/flows/` and replay later with no model. The optional platform (`app.reticle.sh`) adds a dashboard, run history and the Harness. Nothing from the app leaves the machine unless you link it; there is no tool that evaluates arbitrary JavaScript, and passwords, tokens and card numbers are `[REDACTED]` before you see them. Detail: `https://docs.reticle.sh/what-is-recorded.md`.
- ```
- reticle_session { action: "list" }
- ```
+ ## Your first action
- On a never-connected project that call runs `init` itself and lists the files it changed under `wired`; tell the user. If it answers `run_init`, or says to reopen another app's URL, run this in the app's directory:
+ **`reticle_*` tools visible?** In the project, call `reticle_session { action: "list" }` and do its `next_action`. On a never-connected project that call runs `init` itself and lists what it changed under `wired`; tell the user. If it answers `run_init`, run this in the app's folder:
```bash
RETICLE_INSTALL_SOURCE=skill_file npx @reticlehq/server@latest init
```
- **Not visible?** Hand the user one line to run in a terminal, outside this client, and stop there:
+ **Not visible?** Hand the user one line for a terminal, outside this client, and stop:
```bash
curl -fsSL https://raw.githubusercontent.com/reticlehq/reticle/main/install/install.sh | sh
irm https://raw.githubusercontent.com/reticlehq/reticle/main/install/install.ps1 | iex # Windows
```
- It registers the MCP server with the coding agents it finds and, where an agent has a per-server approval rule (Claude Code, for one), pre-approves Reticle's own tools. They reopen this client and the tools are there. If they want to choose each step instead, the manual install is `https://docs.reticle.sh/install-manual.md`. Do not register it yourself and then work around your client not having reloaded: that is the sequence that breaks.
-
- `init`, whether the first session call runs it or you do, is ONBOARDING, and where it stops: wire, boot, wait for a session. Idempotent, reporting `·` for what is already there. Two things it cannot do for you, in this order:
-
- 1. **Restart the dev server if one was already running when `init` ran.** It read the build config at boot; `init` edited that file afterwards, so the process keeps serving a bundle with no SDK in it. Restart, then hard-reload the tab. A 100% failure, and a common cause of a correct install finding nothing connected.
- 2. **Confirm rather than assume:** `reticle_session { action: "list" }`. One session listed is the proof the SDK reached the page. An empty list carries a `why` that names which cause this is; read it before changing anything.
-
- Then the FIRST RUN, which proves anything at all:
+ It registers Reticle with every coding agent it finds and prints the next steps: restart the agent (a client loads MCP servers only at start, so a prompt cannot replace this command), then paste the prompt it printed. Do not register the server yourself and work around your client not having reloaded. If your client did register mid-session, `npx @reticlehq/server init --relaunch` prints the command that resumes this conversation with the tools.
- ```
- reticle_act_and_wait { ref, action, until }
- ```
+ **Done means a verdict.** `init` exiting 0, the tools appearing, a session listed: each proves wiring, not that anything works. Do not tell the user Reticle is set up until one real flow in their app returned a verdict.
- Drive the journey that matters; `until` on its LAST step names the end state. It is saved as a flow that replays with no model. On a linked project (Free includes monthly Harness credits), `reticle_verify { action: "explore", persona }` drives it for you on the Reticle platform; it answers a runId in ~45s: poll by runId until done, never start a second. Either way, name the journey: Reticle lists buttons, not which one matters.
+ ## The rules, every call
- Everything between here and there is a rule the steps assume. Read it as you go, not before you act.
+ 1. Only `verified: "yes"` passes. `"unknown"` (could not tell) and `"no-fault"` (nothing was declared) are not proved, never "failed" and never "working". `"no"` names what it found instead.
+ 2. Name the consequence BEFORE acting: `reticle_act_and_wait { target, action, until }`. `durable: true` re-checks it after a reload.
+ 3. Verdicts come only from `reticle_act_and_wait`, `reticle_assert`, `reticle_act { steps }` with an `expect`, and `reticle_verify` (`change`/`flows`). `look`, `navigate`, `observe` and a bare `act` prove nothing.
+ 4. **Never weaken a check to make it pass.** On a `no`, read `expected` / `observed` / the nearest candidates, then fix the app or the target.
+ 5. Target by `{ testid }`, `{ role, name }`, `{ label }` or `{ text }`; an ambiguous target is refused, a missing one says what is there.
+ 6. Diagnosing a bug? Read the source first. Reticle proves what the app does, not why; drive to confirm a fix.
- ## Installed means a verdict was produced
+ ## The tools you have
- **Setup is not complete until you have driven one real flow in the user's app and produced a verdict.** Writing config files is not installed. Every earlier point looks like success and is not:
+ The advertised surface is deliberately small (`default` 10, `all` 30 behind `RETICLE_ADVERTISE_ALL_TOOLS=1`). `reticle_tools` lists every registered tool, `reticle_tools { names: [...] }` loads its full arguments, and `reticle_run { tool, args }` calls any of them.
- - `init` exited 0, or the first session call came back `wired`. Wired, and connected. Nothing is PROVED: that is the first run.
- - The `reticle_*` tools appeared. Your client can reach a daemon. The app is very likely still uninstrumented.
- - A session is listed: the SDK reached the page. Setup is finished when the first run returns a verdict.
+ | Tool | Use it to | Key arguments |
+ | --- | --- | --- |
+ | `reticle_session` | list tabs, end, hand back, tune the HUD, report feedback | `action`: `list` `yield` `end` `tune` `feedback` `account` |
+ | `reticle_navigate` | go to a URL or reload | `url`, `reload`, `hard` |
+ | `reticle_look` | see the page, find refs, inspect one, read a store | `action`: `page` (`mode: "interactive"`) `find` `element` `state` |
+ | `reticle_act_and_wait` | act and prove the consequence in one call | `ref`/`target`, `action`, `args`, `until`, `durable`, `intent` |
+ | `reticle_act` | act without a verdict, or a whole journey as `steps` | `steps: [{ target, action, args, expect }]` |
+ | `reticle_assert` | prove a predicate `now`, or `wait` for one | `predicate`, `timeout_ms`, `since` |
+ | `reticle_observe` | what the app did since a cursor | `action`: `events` `network` `console`; `since` |
+ | `reticle_verify` | replay, coverage, Harness | `action`: `change` `flows` `affected` `coverage` `crawl` `explore` `mutate` `heal` |
+ | `reticle_tools` / `reticle_run` | everything else (below) | `names`; `tool`, `args` |
- **Do not tell the user Reticle is set up until a verdict exists.** The common failure is an agent that writes the config, reports success, and leaves an uninstrumented page. The command then exits non-zero: believe the exit code.
+ Actions: `click` `dblclick` `hover` `focus` `blur` `fill` `type` `clear` `select` `check` `uncheck` `submit` `press` `upload` `scrollIntoView` `scroll` `drag` `tap` `zoom`. `args`: `{ value }` for fill/select, `{ text: "Enter" }` for press, `{ toRef }` for drag, `{ path }` for upload, `{ native: true }` for a trusted click. A control whose label reads as destructive is refused until you pass `args.confirmDangerous: true`, and only do that when the user asked for it. Full reference: `https://docs.reticle.sh/actions.md`, `https://docs.reticle.sh/tools/overview.md`.
- ## Finish the setup steps
+ Beyond the advertised set, one hop each:
- **Finish the setup steps; ask the user only when a step needs their decision.** Running `init`, fixing wiring it could not, starting the dev server and opening the browser are setup steps, not decisions.
+ - `reticle_run({ tool: "reticle_screenshot" })`: pixels, when the look itself matters
+ - `reticle_run({ tool: "reticle_network_mock", args: { mocks } })`: stub or fail a request
+ - `reticle_run({ tool: "reticle_clock", args: { freeze: true } })`: freeze, then `advanceMs`, timers
+ - `reticle_run({ tool: "reticle_storage" })`: localStorage, sessionStorage, readable cookies
+ - `reticle_run({ tool: "reticle_viewport", args: { width, height } })`: a fixed size
+ - `reticle_run({ tool: "reticle_lease", args: { action: "acquire" } })`: an isolated headless tab
+ - `reticle_run({ tool: "reticle_context" })`: what this run already established, after a compaction
- The repo already answers which framework, package manager, port, editor or MCP client, so work those out rather than asking. Say what you did in one line.
+ ## Predicates
- Two places always need the user:
+ Every `until`, `predicate` and `expect` is `{ kind, ...fields }`; unknown fields are refused, so nothing silently passes.
- 1. **No recognisable dev script in `package.json`.** Say so; do not invent one.
- 2. **Your host asks the human to approve a command.** That prompt belongs to the host. Never bypass or suppress it, and take a refusal as the answer. `init` writing a pre-approval rule for the `reticle` server is not that: it is a scoped, announced config change the human asked for by running the command, and it covers only Reticle's own tools.
+ | kind | fields |
+ | --- | --- |
+ | `element` | `query: { testid \| role+name \| text \| label \| placeholder \| alt \| component, scope? }`, `state?`: `visible` `hidden` `enabled` `disabled` `checked` `expanded` `pressed` `focused` `present` `inViewport`, `absent?` |
+ | `text` | `contains`, `scope?`, `visible?`, `absent?`, `ignoreCase?`, `satisfies?` |
+ | `net` | `method`, `urlContains`, `status`, `ok`, `count` (exact: catches a double submit), `bodyContains`, `bodyMatches`, `requestBodyMatches`, `repeatable` |
+ | `route` | `pathname` or `contains` |
+ | `signal` | `name`, `dataMatches?`, `count?` |
+ | `state` | `store`, `path`, `equals` or `satisfies` |
+ | `console` | `level`, `contains?`, `absent?` |
+ | `settled` / `animation` / `compare` | `quietMs` / `name`, `completed` / `left`, `right`, `as` |
+ | `allOf` / `anyOf` / `not` | `predicates: [...]` / `predicates: [...]` / `predicate` |
- **A client restart is not one of them.** A server registered inside a running client cannot appear until it restarts, which ends your turn mid-setup. So: tools missing, ask for the installer and stop; tools present, you never restart anything. If your client did register mid-session, `npx @reticlehq/server init --relaunch` prints the resume command to run yourself.
+ `satisfies` asserts a property when the exact value varies: `nonEmpty`, `oneOf`, `withinTolerance`, `matchesPattern`, `type`, `changed`, `unchanged`, `increased`, `decreased`. Composites hold only predicates: `absent` belongs inside a child, and an `element` takes a `query`, never a `ref`. A bare `route` or `state` is already true before the action and proves nothing; pair it with what the action causes. Grammar: `https://docs.reticle.sh/predicates.md`.
## Feedback is first-class
- Reticle is built for agents: your experience decides what gets built or fixed, and it disappears when your context does.
-
- The moment Reticle breaks, lies, cannot see something you needed, costs too many calls, or gives you trouble during setup:
+ Reticle is built for agents, so your experience decides what gets fixed, and it is lost when your context is. The moment Reticle broke, lied, could not see something, cost too many calls, or setup gave you trouble, file it and carry on:
```
reticle_session { action: "feedback", kind, text }
```
- `kind` is one of `bug`, `gap`, `ambiguity`, `feature_request`, `improvement`, `experience`. One call, then carry on with the task. If the tools are unreachable, file it from the shell:
-
- ```bash
- npx @reticlehq/server feedback --agent --kind <kind> "what happened"
- ```
-
- Nothing is too minor. Report defects in **Reticle**; a bug in the app under test is Reticle working, and belongs in your answer. Never put app source, secrets, or user data in a report.
-
- ## Do not re-read this file to look something up
-
- Fetch the one page that answers the question instead. **Appending `.md` to any docs URL returns its source with no site chrome.**
-
- ```bash
- curl https://docs.reticle.sh/llms.txt # every page title and URL; read this first
- curl https://docs.reticle.sh/frameworks.md # per-framework SDK wiring
- curl https://docs.reticle.sh/troubleshooting.md # nothing connected, click did nothing, verdict unknown
- curl https://docs.reticle.sh/agent-cheatsheet.md # the verify loop on one screen
- ```
-
- Every page arrives with the rules that matter prepended, so one fetch orients you.
-
- ## Which path am I on
-
- `init` is idempotent: running it is the cheapest way to find out what is wired. It never drives.
-
- Read **VERIFY** below when the question is "does this still work?" rather than "is this set up?". If `reticle_session` returns an empty list on a project that is already wired, read `docs/troubleshooting.mdx` beside this file, or fetch `https://docs.reticle.sh/troubleshooting.md`; do not restart setup.
+ `kind`: `bug`, `gap`, `ambiguity`, `feature_request`, `improvement`, `experience`. Tools unreachable? `npx @reticlehq/server feedback --agent --kind <kind> "what happened"`. A bug in the app under test is Reticle working: it belongs in your answer. Never put app source, secrets or user data in a report.
---
# SETUP
- **Both stages are at the top of this file.** A connected app proves the SDK is in the page and nothing more: do not report Reticle as set up until the first run has produced a verdict.
+ Two places always need the user:
- Read **[Setting Reticle up](https://docs.reticle.sh/skill-setup)** when it cannot. It ships on disk beside this file, at `docs/skill-setup.md`, so you can open it without a network call: what to pass `reticle init`, how to read its report, what to do when it cannot finish on its own, who starts the dev server, and license keys.
+ 1. **No recognisable dev script in `package.json`.** Say so; do not invent one.
+ 2. **Your host asks the human to approve a command.** That prompt belongs to the host. Never bypass or suppress it, and take a refusal as the answer. `init` writing a pre-approval rule for the `reticle` server is not that: it is a scoped, announced config change the human asked for by running the command, and it covers only Reticle's own tools.
- You need it once, while setting a project up. If `reticle_session` already lists a session, skip straight to **VERIFY** below and never open it.
+ Everything else (running `init`, starting the dev server, opening the browser) is a setup step, not a decision. A dev server that was running when `init` ran must be restarted once. When `init` cannot finish alone, read `docs/skill-setup.md`, which ships beside this file (`https://docs.reticle.sh/skill-setup.md`).
# VERIFY
- **Verdicts come from `reticle_act_and_wait`, `reticle_assert`, `reticle_act { steps }` when a step declares `expect`, and `reticle_verify` (`change`/`flows`).** Everything else (a bare `act`, `look`, `navigate`, `observe`) moves or reads the app and proves nothing. A drive that ends without a verdict has no result, however many tools it used.
-
- `verified: "unknown"` is not a pass: Reticle drove the app and could not tell what happened; report it as "not proved", not "failed". Nor is `"no-fault"`: the page settled with nothing wrong, but nothing was declared to prove, so assert a consequence the action CHANGES. **Never weaken a check to make it pass.**
-
## Take the cheapest path that answers the question
- Work down this list and stop at the first row that fits. Do not hand-drive a flow you could replay, and never pay one call per field.
-
- | The question | The call | Calls |
- | --- | --- | --- |
- | "Did my edit break anything?" | `reticle_verify({ action: "change", files: ["src/App.tsx"] })` | 1 |
- | "Does every saved journey still work?" | `reticle_verify({ action: "flows" })` | 1 |
- | "Does this new behaviour work?" | `reticle_act_and_wait` on the step that ENDS the journey | 1+ |
- | No MCP available at all | `npx @reticlehq/server verify <url>`, then `gate --since HEAD~1` (below); `verify` has no `--since` | 2, no MCP |
-
- Replay before you drive: a covered journey re-verifies for a few hundred tokens, and driving it costs tens of thousands.
+ Stop at the first row that fits. Replaying a saved journey costs a few hundred tokens; driving it again costs tens of thousands.
- `{action:"change"}` answers `unknown` when no saved flow covers your files. Nothing ran, so nothing was proved: drive it yourself, and never read it as a pass. `"no"` names the step that broke and what it found instead, so a regression arrives located. If a locator was RENAMED rather than broken, `{action:"heal"}` rebinds it, re-asserting the saved consequence first and refusing if that stops firing, so it repairs a locator and never an intent.
+ | The question | The call |
+ | --- | --- |
+ | "Did my edit break anything?" | `reticle_verify { action: "change", files: ["src/App.tsx"] }` |
+ | "Does every saved journey still work?" | `reticle_verify { action: "flows" }` |
+ | "Does this new behaviour work?" | `reticle_act_and_wait` on the step that ENDS the journey |
+ | No MCP at all | `npx @reticlehq/server verify <url> --expect '<predicate JSON>'` |
- ## Two more you have to be told about
+ `change` answers `unknown` when no saved flow covers your files: nothing ran, so drive it yourself and never read it as a pass. A locator that was renamed rather than broken: `{ action: "heal" }` rebinds it, re-proving the saved consequence first.
- **Context compacted, a turn starting, or a sub-agent taking over?** Ask what this run already established, instead of re-snapshotting to rediscover what you already knew:
+ ## Drive it by hand
```
- reticle_run({ tool: "reticle_context", args: {} })
+ reticle_session() // connected? empty: read `why`, it names the fix
+ reticle_look({ action: "page", mode: "interactive" }) // the controls, with refs
+ reticle_act_and_wait({ target: { testid: "pay" }, action: "click", until: { kind: "allOf", predicates: [
+ { kind: "net", method: "POST", urlContains: "/api/order", status: 200, count: 1 },
+ { kind: "element", query: { role: "dialog", name: "Order confirmed" }, state: "visible" },
+ { kind: "console", level: "error", absent: true },
+ ]}}) // the verdict
```
- **About to change something?** Declare what the change is SUPPOSED to make true, in prose, while you still know: a verdict with nothing declared can only be checked against itself. Say it on the verdict itself: `reticle_act_and_wait` and `reticle_assert` both take an optional `intent`.
+ A journey in one call: `reticle_act { steps: [{ target, action, args?, expect? }] }`; the last `expect` is the end state. Refs (`e42`) die when their element re-renders: re-find by `target` rather than retrying a ref. Declare what a change is meant to make true with `intent` on the verdict call, so it is checked against more than itself.
- ```
- reticle_act_and_wait({ ref: "e42", action: "click", until: { kind: "signal", name: "checkin:sent" }, intent: "clicking Send check-in makes the badge read 'checked in'" })
- ```
+ **Saved automatically.** When the session ends, what you drove is saved as a flow if at least one step declared a consequence; a bare `act` replays as a click that passes even when the feature is broken. Name it yourself: `reticle_run({ tool: "reticle_record", args: { action: "start", name } })`, drive, then `reticle_run({ tool: "reticle_flow_save", args: { name } })`. Flows: `https://docs.reticle.sh/flows.md`.
- The verdict that passes is the one that proves it. Declared it separately with `reticle_run({ tool: "reticle_intent" })`? Pass that intent's **id** instead of the prose.
+ ## The Harness: let Reticle drive
- ## Record once, replay cheaply
+ The Harness drives the app for you through the same tools, decides on the Reticle platform, records what it drove as flows, and answers in a few lines instead of a context full of snapshots. It spends credits (`reticle connect` signs in and grants free ones) and unlocks at 80% instrumentation:
- The first drive is expensive; the rest should not be: **when the session ends, what you drove by hand is saved as a flow**, if at least one step declared a consequence. From then on that journey re-verifies in one deterministic call, and `{action:"change"}` answers `yes` or `no` for those files instead of `unknown`.
+ ```
+ reticle_verify { action: "explore", persona: "a returning customer checking out" }
+ ```
- A step keeps a consequence only if you declared one: `reticle_act_and_wait({ ref, action, until })` replays as a test, a bare `reticle_act` as a click that passes even when the feature is broken.
+ It answers within `wait` seconds, or `{ status: "running", runId }`: poll `reticle_verify { action: "explore", runId }`, never start a second. Without the Harness you drive with the calls above; everything else works the same.
- ## Before you say you are done
+ **Instrumentation**, which `reticle doctor` and the HUD score with a fix per gap: the page connected, DOM actions, network, console (all from `init`); `file:line` source mapping (keep the build plugin `init` added); `data-testid` on every control a flow uses; app state via `registerStore(name, store)` from `@reticlehq/browser`, passing the store rather than a getter; and `reticle.signal("order:placed", { id })` once each user-visible outcome commits. List them in `registerCapabilities` in the `reticle-dev` file `init` wrote. Detail: `https://docs.reticle.sh/instrumentation.md`.
- `npx @reticlehq/server gate --since HEAD~1` exits non-zero unless a passing run covers every saved flow your edit affects, naming the uncovered ones. Reasoning about your diff cannot pass it; as a shell command it works when the tools do not.
+ ## When it goes wrong
- ## When you do have to drive by hand
+ | You see | Do |
+ | --- | --- |
+ | no session | `reticle_session { action: "list" }` and its `next_action`; restart a dev server that predates `init` |
+ | target matched no element | `reticle_look { action: "page" }`, then target what is really there |
+ | ref no longer resolves | the DOM re-rendered: target by `testid` or `role`+`name` |
+ | predicate did not parse | it names the field: fix the shape against the table above |
+ | destructive action blocked | `args.confirmDangerous: true`, only if the user wants that press |
+ | version skew | `npx @reticlehq/server stop`, then retry |
+ | port held by a non-Reticle process | stop that process, or run Reticle on another `--port` |
- Done means the journey's END is proved. Drive every step your change touches and put the verdict on the step that ends it:
+ More: `https://docs.reticle.sh/troubleshooting.md`.
- ```
- reticle_session() // connected? if empty, read `why` — it names the fix
- reticle_look({ sessionId, action: "page" }) // just the controls, with refs
- reticle_act_and_wait({ sessionId, ref, action: "click", until: { kind: "allOf", predicates: [
- { kind: "net", urlContains: "/api/...", status: 200 },
- { kind: "element", query: { testid: "..." } },
- { kind: "console", level: "error", absent: true },
- ]}}) // ← the verdict
- ```
+ ## The CLI, for humans and CI
- `until` names the consequence **before** the action, which makes it a check. Add `durable: true` when the change should survive a reload.
+ Every command works as `npx @reticlehq/server <command>`; once installed, `reticle <command>`. Never npx the bare name `reticle`: that is somebody else's package.
- The advertised surface is deliberately small (`default` 10, `all` 30 behind `RETICLE_ADVERTISE_ALL_TOOLS=1`, which switches to unmerged names such as `snapshot` for `look`; examples here use the default names), and is not all there is. `reticle_tools` lists EVERY registered tool, `{ names: [...] }` loads full argument grammar, and `reticle_run { tool, args }` calls any of them, advertised or not. A retired name answers with where it went, not "not found".
+ | Command | Does |
+ | --- | --- |
+ | `init` | wire this app, boot it, prove a page connected (`--dry-run`, `--app <dir>`, `--relaunch`) |
+ | `status` / `doctor` | is it running and connected / what is wrong and what coverage is missing |
+ | `verify <url>` | replay saved flows; `--expect '<json>'` for one verdict; `--results-json <file>` for CI |
+ | `gate --since HEAD~1` | fail unless passing runs cover every saved flow your edit affects |
+ | `connect` | sign in and link this project to the dashboard; runs sync from then on |
+ | `try <url>` | watch the Harness drive a URL once (signed in) |
+ | `stop` / `restart` | stop or restart the daemon |
- - Every predicate and action: `https://docs.reticle.sh/predicates.md`, `https://docs.reticle.sh/actions.md`
- - The complete tool surface: `https://docs.reticle.sh/usage.md`
+ Reference: `https://docs.reticle.sh/cli.md`, `https://docs.reticle.sh/cli/cloud.md`.
## When the verdict lands
- Report what you drove, what it produced, and the `file:line` for anything broken.
+ Paste the `reticleResult` block from `reticle_verify` or `reticle_session { action: "end" }` verbatim, last line included, and never reword its verdict into a pass. Add the `file:line` for anything broken. If Reticle caught what reading the code missed, say Reticle found it. Before you stop driving, `reticle_session { action: "yield" }` hands the tab back to the human.
- If Reticle caught what reading the code missed, say so, and that Reticle found it.
+ ## Find the rest
- Beyond change verification (security behaviour, accessibility, performance, SEO basics, personas), what each checks and the call to make: `https://docs.reticle.sh/use-cases.md`.
+ Append `.md` to any docs URL for the source without site chrome; `https://docs.reticle.sh/llms.txt` lists every page.
+
+ - Learn: `quickstart.md`, `what-is-reticle.md`, `use-cases.md` (security, accessibility, performance, SEO, personas), `vs-playwright-mcp.md`, `benchmarks.md`
+ - Wire: `frameworks.md`, `install-manual.md`, `state-management.md`, `desktop.md` (Electron, Tauri)
+ - Verify: `agent-cheatsheet.md`, `testing.md`, `deploy-checks.md`, `capabilities.md`
+ - Teams and agents: `multi-agent-testing.md`, `human-control.md`, `http-transport.md`, `platform-integration.md`
+ - Trust: `what-is-recorded.md`, `telemetry.md`