A process can be alive, answer a prompt, and still be completely unready for real work.
That is the dangerous middle state for coding agents and OpenClaw-style assistants: the container is healthy, the model responds, and the demo looks fine, but the first real tool call fails because the runtime cannot persist state, the browser profile is empty, the service identity is wrong, or the configured model endpoint is reachable only from the developer laptop.
I use a deployment readiness check to catch those failures before handing an agent a long-running task. It is deliberately smaller than a full end-to-end evaluation. The goal is to answer one question:
Can this exact runtime accept a task, perform one safe tool call, preserve the evidence, and tell me what is not ready?
1. Separate liveness from readiness
A liveness check asks whether the process is running. A readiness check asks whether the dependencies required by the next operation are usable.
Keep the endpoints separate:
GET /live -> 200 while the process is alive
GET /ready -> 200 only when required dependencies pass
A useful readiness response should identify the failed boundary without leaking credentials:
{
"ready": false,
"checked_at": "2026-08-08T13:20:00Z",
"checks": {
"model_endpoint": {"ok": true, "latency_ms": 184},
"tool_registry": {"ok": true, "tools": 7},
"state_store": {"ok": false, "error": "read-only filesystem"},
"browser_profile": {"ok": true, "profile": "worker-a"}
}
}
Do not return a green result merely because the model endpoint works. If the agent cannot write its run record, a successful answer may be impossible to recover or audit.
2. Define the minimum safe task
The readiness probe should use a task that is deterministic enough to compare across deployments, safe to repeat, representative of the first tool path you care about, and small enough to finish within a few seconds.
For a coding agent, that might be reading a fixture file and returning its SHA-256 digest. For a browser agent, it might be opening a controlled page and extracting a known heading. For an MCP client, it might be listing tools and invoking a read-only tool with fixed arguments.
Avoid using a real ticket, production database, mailbox, or payment API as the probe. A readiness check is run frequently, including after deploys and restarts. It should never create an irreversible side effect.
Record the probe contract in version control:
probe_version: 3
allowed_tools:
- read_fixture
- emit_probe_result
expected:
status: SUCCEEDED
digest: "sha256:..."
forbidden:
- network_write
- credential_export
- filesystem_delete
Versioning matters. If the tool schema or expected result changes, you want to know whether the deployment failed or the probe itself changed.
3. Check the control plane, not only the model
Before the probe runs, validate the boundaries around the model:
- Configuration: resolve the intended model, tool server, workspace, and environment. Log names and versions, not secret values.
- Identity: confirm the runtime identity and credential scope. A token existing is not proof that it can perform the required operation.
- Tool registry: load the exact schemas that will be presented to the model. Hash the normalized registry so unexpected changes are visible.
- State store: write and read a temporary probe record, then delete or expire it. Check that the store preserves the run ID and timestamps.
- Workspace: verify the expected directory, permissions, and a clean disposable fixture.
- Browser surface: if browser automation is enabled, verify the profile, executable, viewport, and a controlled navigation target.
- Network policy: test the permitted route, not just DNS. A service can resolve a hostname while egress policy still blocks the actual request.
A compact shell wrapper can fail closed:
set -euo pipefail
base="${AGENT_URL:?set AGENT_URL}"
curl --fail --silent "$base/live" >/dev/null
ready="$(curl --fail --silent "$base/ready")"
printf '%s\n' "$ready" | jq -e '.ready == true' >/dev/null
curl --fail --silent \
-H 'content-type: application/json' \
-d '{"probe_version":3,"fixture":"read-only-digest"}' \
"$base/probe" | jq -e '.status == "SUCCEEDED"'
The wrapper should return a non-zero exit code for an unknown result. Treating a timeout as success is how an unhealthy agent gets traffic.
4. Preserve evidence for every failed gate
For each check, capture a run ID and probe version, runtime and deployment version, dependency name and normalized request metadata, start and finish timestamps, result state such as SUCCEEDED, FAILED_BEFORE_SEND, FAILED, or UNKNOWN, and a redacted error class with a remediation hint.
The distinction between FAILED_BEFORE_SEND and UNKNOWN is important. If the process crashed before dispatch, retrying a read-only probe is usually safe. If it crashed after dispatch but before recording the response, the control plane cannot assume the operation did not happen. The probe must either be idempotent or have a reconciliation step.
Do not put full prompts, cookies, authorization headers, or browser page contents into a general readiness log. Store sensitive evidence in a separately access-controlled location and keep the readiness record useful without making it a credential dump.
5. Test the transitions you actually fear
A green probe on a quiet machine is not enough. Add failure injection to the deployment check in a staging environment:
| Failure | Expected result |
|---|---|
| model endpoint timeout | readiness fails with a bounded timeout |
| tool schema cannot load | probe is not admitted |
| state store becomes read-only | readiness fails before task dispatch |
| browser profile is missing | browser capability is not advertised |
| process exits after tool dispatch | result becomes UNKNOWN, not success |
| network route is denied | the blocked dependency is named |
| old probe version is sent | request is rejected clearly |
Run the matrix after an image change, configuration change, credential rotation, and host migration. These are the moments when “it worked in the demo” most often diverges from “it is safe to leave running.”
6. Make readiness a gate, not a dashboard decoration
There are three practical enforcement points:
- Deployment: do not mark the new instance ready until the probe passes.
- Scheduler: do not assign new work to an instance whose readiness lease has expired.
- Agent loop: re-check critical capabilities immediately before a side-effecting tool call.
The scheduler should use a short-lived readiness lease rather than a permanent boolean. A process that passed at startup may lose its state store or browser session later. Every lease should include the runtime ID, probe version, capability set, and expiry time.
A readiness check cannot prove the agent will produce a correct answer. It can prove something narrower and valuable: the deployed control plane is able to execute the smallest safe workflow and leave enough evidence to diagnose failure.
That is the bar I want before an agent receives a real repository, browser profile, or long-running automation task. First prove the runtime is ready. Then evaluate the model.
Top comments (0)