diff --git a/changelog.mdx b/changelog.mdx
index 94bf72e..f297d98 100644
--- a/changelog.mdx
+++ b/changelog.mdx
@@ -7,6 +7,24 @@ description: "Stay up to date with the latest agentsfleet product updates, new f
agentsfleet is in **stealth-mode testing** and pre-production. APIs and agent behavior may change between releases without long deprecation windows. Email [agentsfleet@agentmail.to](mailto:agentsfleet@agentmail.to) if you want a hand calibrating an agent or to join as a design partner.
+
+ ## A hardened runner completes credentialed work again
+
+ On runners with the full sandbox tier, every model call that carried a credential failed within milliseconds. The sandbox granted its scratch space as read-only while the mount beneath it was writable, and the engine writes each call's authorization header to a private scratch file — so the very first credentialed call died. Both layers now read one shared list of writable paths, so they cannot disagree again.
+
+ ## What's new
+
+ - **Run checks can catch this class of fault.** The runner's check panel gains a fourth line: the scratch dir accepts a write inside the sandbox. It runs under the same restrictions your work runs under, so a sandbox that would fail your fleets fails the check first.
+ - **The runner page reads plainer.** The lease filter is labeled `Filter` with an `Apply` button, the filter accepts `workspace: and fleet:` written exactly as its hint shows, and the lease and activity tables use the same `Time` and `Duration` column names as the events list.
+ - **Every runner action carries an icon,** and **Cordon** and **Drain** show as disabled with the reason "Not active yet" until they are ready to use.
+ - **A refresh button re-reads the runner page** on your click — after you request checks, the verdict appears without a full page reload.
+ - **Runner states are explained where they show.** The state chip links to [the states a runner shows](/runners#the-states-a-runner-shows), and that section now defines every admin state and liveness value on the page.
+
+ ## Bug fixes
+
+ - **The check panel's relative timestamp shows the absolute time on hover,** matching the lease table's time column.
+
+
## Installing a fleet is one step
diff --git a/runners.mdx b/runners.mdx
index fb78bbf..e3bd925 100644
--- a/runners.mdx
+++ b/runners.mdx
@@ -58,6 +58,29 @@ The three isolation settings differ in what enforces the boundary:
| Nested container | The fleet runs inside a container on a Linux host or virtual machine. |
| None | No sandbox. Development builds only. |
+### The states a runner shows
+
+The runner page shows two facts side by side: what you have told the runner to do, and whether the host is answering.
+
+The first is the admin state. You set it with the actions below. It moves on its own in one case only: a draining runner becomes `drained` once its last lease finishes.
+
+| Admin state | Meaning |
+|---|---|
+| `active` | Takes work. The normal state. |
+| `cordoned` | Takes no new work. Its running work stays fenced until it expires or moves. |
+| `draining` | Takes no new work and finishes what it has. Becomes `drained` on its own once the last lease ends. |
+| `drained` | Finished draining. Idle, and stays there until you change it. |
+| `revoked` | Its token is blocked. This is terminal for the enrolled host. |
+
+The second is liveness. The host reports it through its heartbeat; you cannot set it.
+
+| Liveness | Meaning |
+|---|---|
+| `registered` | Enrolled, but no heartbeat has arrived yet. |
+| `online` | Heartbeating and idle. |
+| `busy` | Heartbeating and running work. |
+| `offline` | Heartbeats stopped. Its work expires and another runner takes it. |
+
### When a runner stops taking work
A runner reports what its kernel can actually enforce on every heartbeat. `agentsfleetd` compares that report against the policy you assigned.