Target readiness
Preview environments, sleeping stacks and local services can answer with a placeholder. A paused stack might still return HTTP 200 with a “this app is paused” page. Browser steps then fail with assertions about missing content, which look like application regressions.
Configure HTTP health probes for the selected target. Before admitting new work,
Reflow sends one GET to each probe. A failure returns target_not_ready before
any new run or test step starts.
Readiness is opt-in and HTTP-only. It does not load pages, run scripts, wait for a selector or check page titles.
Configure probes
Section titled “Configure probes”Write a JSON file listing the probes. This generic example checks an application route, a separate API and an identity provider:
{ "timeoutMs": 10000, "probes": [ { "url": "/login", "status": [200], "headers": { "absent": ["x-app-paused"] } }, { "url": "https://localhost:8080/healthz", "status": [200] }, { "url": "http://localhost:35291/health", "status": "any" } ]}Select it with the same target URL and group you already use:
reflow target https://localhost:5173/ --group my-app --collection <collection-id> \ --allow-origin https://localhost:8080 --allow-origin http://localhost:35291 \ --readiness /absolute/path/to/readiness.jsonReflow copies the configuration when you select the target. Editing the file
later has no effect until you select the target again with --readiness.
The file must be a regular file, not a symbolic link.
For the same connection, checkout, collection, URL, group and scope, omitting
--readiness keeps the current probes. Use --clear-readiness to remove them.
In local MCP, pass the same object inline to manage_execution with
action: "target":
{ "action": "target", "url": "https://localhost:5173/", "group": "my-app", "readiness": { "timeoutMs": 10000, "probes": [{ "url": "/healthz", "status": [200] }] }}Omit readiness to keep the current probes, or pass readiness: null to clear them.
Selecting a target starts a new evidence epoch, including when only readiness
changes. Earlier step results cannot be reused even if the URL and group stay
the same. Configure readiness when you first select the
target, then repeat plan and apply as usual.
Probe rules
Section titled “Probe rules”| Field | Meaning |
|---|---|
timeoutMs | Total time for all probes together, 1 to 60000 milliseconds. Default 10000. |
probes | 1 to 8 probes, checked concurrently. Results retain configuration order; all must pass. |
probes[].url | A path relative to the target, such as /healthz, or an absolute HTTP(S) URL. |
probes[].status | Status codes that count as ready. Default [200]. Use "any" to accept any HTTP response. |
probes[].headers.absent | Response header names that must not be present. |
probes[].headers.present | Response header names that must be present. |
probes[].headers.equals | Map of name: value that must each appear exactly once with exactly that value. |
Header names are matched case-insensitively. A header can’t be both required and forbidden.
Readiness needs a target URL. An absolute probe URL must use the target origin or an origin you have already
granted with --allow-origin. Readiness never adds a grant. Credentials in URLs,
wildcards and non-HTTP schemes are refused when you select the target.
A response is ready only when its status is in the list. Any HTTP response counts
only when you say "status": "any"; use that for a service whose reachability is
enough, such as an identity provider that answers its health route with a
redirect.
What a probe does
Section titled “What a probe does”Each probe is a single plain GET:
- It does not follow redirects. A redirect is judged by its own status and headers.
- It sends no cookies, no binding or team request headers, and no credentials.
- It doesn’t retry or poll, and it never tries to wake a paused service.
- It doesn’t run a browser, page scripts or DOM checks.
- HTTPS uses normal certificate verification against the system and default CAs. There is no option to skip TLS verification.
- Reflow keeps the origin, status, readiness and a short reason for each probe. It does not keep response bodies, paths or query strings.
These are real network requests to your services. Point probes at health
endpoints that are safe to call repeatedly, such as /healthz, /health or a
lightweight login page. Don’t use routes that create sessions, send email or
change data.
When probes run
Section titled “When probes run”Probes run only before Reflow admits new work:
reflow plannever sends readiness requests.- An
applywhere every step reuses earlier evidence sends none. - Reconciling an existing request ID sends none.
applywith steps to execute checks all probes first, then admits the work.
Readiness requests are separate from test steps. They never become step results, and test steps never run during the check.
When the target is not ready
Section titled “When the target is not ready”All configured probes run concurrently under the same total deadline. One failure does not hide the other services. The CLI and MCP return
target_not_ready with the origin, status (when one was received) and reason
for every configured probe. A probe still waiting when the deadline expires reports timed_out; completed observations retain their outcome. Reasons include:
| Reason | Meaning |
|---|---|
status_mismatch | The status is not in the probe’s status list. |
header_must_be_absent:<name> | A forbidden header was present, for example a paused marker. |
header_missing:<name> | A required header was missing. |
header_mismatch:<name> | A header did not have the exact expected value. |
unavailable | No usable HTTP response, for example a refused connection or TLS failure. |
timed_out | The total timeoutMs ran out. |
cancelled | The request was cancelled. |
No work was admitted, so there is no new run or step result to taint. The CLI
exits with code 75 (target_not_ready, a temporary environment refusal). Failed
tests and other command errors use exit code 1. For a readiness refusal,
apply --json reports admission: "none" and error.code: "target_not_ready".
Earlier outcomes are unchanged, including steps whose completion is still
unknown. Those still need inspection and an explicit taint before they run again.
Start or resume the paused service yourself, then repeat plan and apply.
A passing check is a point-in-time observation. It does not guarantee the target stays ready while the run continues. A service that pauses mid-run still produces ordinary step failures.
Readiness covers HTTP status and headers only. Checks for a page title, DOM selector or browser-rendered content are not implemented. For an application whose paused page looks identical over HTTP, expose a health route or a response header that tells the two states apart.
Readiness applies to local CLI and MCP plan/apply targets. It does not
configure separate device jobs or the HTTP batch API. See the
Browser plugin for navigation origins and the
getting started guide for target selection.