Skip to main content
The DOM tells you what the app drew. reticle_state tells you what it believes. The gap between those two is where false greens live: a row appears in the table, the store never changed, and a reload makes the row vanish.

Example

Real response:
depth: 2 collapsed the contents to size markers: {…30 keys} rather than thirty keys of JSON. On a large store this is the difference between a cheap look and a very expensive one.

Arguments

Drill in once you know what you want:

You have to register stores first

reticle_state reads what your app registered in src/reticle-dev.ts. With nothing registered, storeNames comes back empty and this tool has nothing to say.
Pass the store, not () => store.getState(). The store form wires subscribe too, so every mutation emits a state diff. The getter form is read-only and silently produces empty diffs, which looks like “nothing changed” and is really “I was never watching”.
That distinction is the single most common instrumentation mistake, and its failure mode is a verdict that passes when it should not.

Why this is the strongest evidence you have

A POST returning 200 proves the server was reachable. A row in the DOM proves React rendered something. Neither proves your application accepted the change. State does. When reticle_act_and_wait reports
that is the app itself saying the login took. A mock that returns 200 without touching state gets caught right there, and nowhere else.

Instrument your app

Registering one store for your most important flow is the highest-value line you can write.
Last modified on August 14, 2026