> ## 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.

> ## Agent Instructions
> Reticle is a dev-only, localhost-only verification layer for AI coding agents. It reads program truth (network, state, console, routing, animations, framework state) from inside a running web app and returns a deterministic verdict with evidence. It is not a screenshot tool and not a browser automation library.
> Only `reticle_act_and_wait` and `reticle_assert` produce a verdict. Every other tool moves or reads the app and proves nothing. A drive that ends without one of those two has no result, however many tools it used.
> A verdict of `verified: "unknown"` is not a pass. It means Reticle drove the app and could not tell what happened. Report it as unknown; never weaken a check to make it pass.
> Package names are scoped `@reticlehq/*`. Run every CLI command as `npx @reticlehq/server <command>`, for example `npx @reticlehq/server init`. `reticle` is a bin name that `@reticlehq/server` installs once it is on your PATH, NOT a package on npm: `npx reticle` fetches an unrelated package published by somebody else, so never run that. The complete tool surface is on the `/usage` page; `/agent-cheatsheet` is the one-screen version.

# @reticlehq/eslint-plugin

> Two lint rules that keep Reticle's signal layer and its comment hygiene self-enforcing.

`@reticlehq/eslint-plugin` exists because conventions rot. Someone adds a mutation, forgets the signal, and every verdict for that flow quietly drops a grade. Nothing breaks, the tests still pass, the evidence just gets weaker. A lint rule is the only way a convention survives contact with a deadline.

**Version 2.8.0. Apache 2.0. Depends on `@typescript-eslint/utils`. Peer dependency: `eslint >= 9`.**

```bash theme={"dark"}
npm i -D @reticlehq/eslint-plugin
```

## Exports

| Export                    | What it is                                                         |
| ------------------------- | ------------------------------------------------------------------ |
| `default`                 | The plugin object: `{ meta: { name: 'reticle' }, rules, configs }` |
| `rules`                   | `{ 'require-signal-on-mutation': ..., 'no-internal-tags': ... }`   |
| `requireSignalOnMutation` | The rule, exported individually                                    |
| `noInternalTags`          | The rule, exported individually                                    |

## The rules

### `reticle/require-signal-on-mutation`

Warns when a store mutation happens without a mapped Reticle signal.

**Message id:** `mutationWithoutSignal`. **Text:** `store mutation without a mapped Reticle signal`.

**Options** (`options[0]`, no additional properties):

| Option         | Type                 | Default                                                                                 |
| -------------- | -------------------- | --------------------------------------------------------------------------------------- |
| `mutators`     | `string[]`           | `[]`. With the default the rule is a no-op, which is deliberate: name your own mutators |
| `signalCallee` | `string \| string[]` | `['reticleSignal', 'signal']`                                                           |

```js theme={"dark"}
'reticle/require-signal-on-mutation': ['warn', {
  mutators: ['setState', 'commit', 'dispatch'],
  signalCallee: ['reticleSignal'],
}]
```

The check is scoped per function: a mutation and its signal must live in the same function body.

### `reticle/no-internal-tags`

Errors on internal design-doc reference codes and internal version strings appearing in comments, file names, directory names or test descriptions. **Message id:** `internalTag`, with a `{ tag }` placeholder. No options.

This one is mostly for contributors to Reticle itself, but the `recommended` config turns it on for everyone.

## The recommended config

One config, `recommended`:

```js theme={"dark"}
import reticle from '@reticlehq/eslint-plugin';

export default [reticle.configs.recommended];
```

Which is exactly:

```js theme={"dark"}
{
  plugins: { reticle: plugin },
  rules: {
    'reticle/require-signal-on-mutation': 'warn',
    'reticle/no-internal-tags': 'error',
  },
}
```

<Warning>
  `recommended` enables **both** rules, and `no-internal-tags` at `error`. An older README
  documented only the first rule, so the second can arrive as a surprise. Enable the rules
  individually if you want just the signal check.
</Warning>

<Card title="Why signals are the strongest evidence" icon="tower-broadcast" href="/instrumentation">
  What a signal proves that a rendered pixel cannot.
</Card>
