Name the consequence before you act
reticle_act_and_wait does both in one hop.
A drive that ends on reticle_act proved nothing
Only reticle_act_and_wait and reticle_assert produce a verdict. Everything else moves or reads the app.
This is not pedantry. Here is a real act_sequence response:
ok: true, and the login failed. ok means the actions were dispatched, which they were. If your run ends there, you have a green tick attached to a broken flow.
Batch the setup, prove the outcome. Use act_sequence for the fills, then act_and_wait on the final click.
Treat unknown as unknown
verified: "unknown" is not a pass, not a failure, and not a rounding error. It means Reticle drove the app and could not tell.
We hit one writing the instrumentation page: a login that genuinely succeeded, signal fired, state changed, verdict.pass: true. And still came back unknown, because the page never settled inside the observation window.
Focus the tab
A backgrounded tab has its timers throttled, which suppresses the quiescence detection Reticle uses to decide a page has settled. Symptoms: actions that appear to do nothing, andunknown verdicts on things that plainly worked.
Every response tells you when this is happening:
refuseWhenThrottled: true if you would rather fail loudly than act into a throttled tab.
Read the buffer note before trusting a negative
Assert exact counts, not vague ones
Scope assertions with since
Without a cursor, an assertion evaluates against the recent buffer, which may contain events from before your action. That passes for the wrong reason: the request you asserted did fire, two clicks ago.
Every act response returns a since. Use it.
Climb the grade ladder
Every verdict reportshonesty.grade. Aim for signal.
Getting from
presence to signal is roughly ten minutes of instrumentation per flow, and it is the highest-leverage work available.
Emit failure signals too. With auth:denied defined, a failed login reports signals seen in this window: auth:denied instead of just “never fired”. The app names its own outcome and the diagnosis lands in one response.
A signal-grade pass can still miss the bug
This is the subtlest entry on the page, and it comes from a controlled A/B run against the same app minutes apart. Same login, same predicate,until: { kind: "signal", name: "auth:granted" }, run twice. Once against a healthy build, once against a build with a persistence bug injected, where the auth token is never written to storage.
Healthy:
storageKeysChanged, and the assertion never asked about it.
If persistence is part of what “it worked” means, assert it:
storageKeysChanged: [] was right there. Read the summary block, not just verified.
Never weaken a check to make it pass
The temptation, when an assertion fails, is to loosen it until it goes green. Sometimes the assertion really was wrong. Usually the app is. If you relax a predicate, you should be able to say why the original expectation was incorrect. “It kept failing” is not that reason.Ask narrowly
Every response carries
cost: { bytes, tokens }. If a loop is expensive, that field tells you which call to fix.
Bind to meaning, not structure
Query by testid, role or label. Assert on signals and state. Both survive the refactor that moves your markup around; a CSS selector does not.End your sessions
Sessions accumulate. Four stale ones pointing at dev servers you restarted an hour ago look completely plausible in a list, and one of them will get picked.yield when you are pausing, end when you are done. Both revive on your next action, so neither is destructive. The difference is what the human watching the panel is told. The panel reads “live” until you say otherwise.
Confirm a navigation landed
reticle_navigate returns confirmed: false by design. A navigation destroys the document the SDK lives in, so it can only report dispatch. Check reticle_sessions for a session at the new URL before acting, and re-snapshot: refs do not survive a new document.
Start with what the app says about itself
Instrument your app
Where most of the quality actually comes from.
Lock it into CI
So the habits survive the week you are not looking.