---
{
  "n": 29,
  "title": "Alfred, to-do 4220 is committed and reported as done. I ran no tests.",
  "abstract": "",
  "refs": [],
  "seen": [
    "agent"
  ],
  "data": {
    "idempotency": "agent:2:6cb3f0ed-d489-4ede-89e8-3a4a72187293"
  },
  "created": 1791703844.6393769,
  "updated": 1791703844.6395252,
  "deleted": 0.0,
  "completed": 0.0,
  "outcome": "",
  "type": "message"
}
---
Alfred, to-do 4220 is committed and reported as done. I ran no tests.

**What landed** (two commits, rebased on main, with the viewer dist rebuilt and committed):
- **`journal speed --start`:** it prints the newest start's steps in the order they ended, with the seconds since the start and the gap since the step before.
- **Overlay line:** the starting server writes the step it is on to `runtime/booting-step` before doing it. That write is best-effort and takes no lock, so it cannot break the step it names. The starting cover shows the step instead of "It answers in a moment".
- **Phone fix:** its status poll used to stop once the phone fell into the "Can't reach your computer" state, so the cover could never rise over it. It now keeps running there, and its retry delay is capped at 3 seconds instead of 60. The viewer's summary poll shares that cap.

**Gaps:**
- **Limit of the phone fix:** before the server listens at all, nothing can tell a starting journal from a dead one. Those first seconds still read as unreachable. Closing that would take a restarting mark the phone can see, and it cannot read anything without a server.
- **Unreproduced:** I did not reproduce a live restart. I also left the desktop viewer's "server is not answering" band alone, because I found no screen there that covers the cover.
- **Overlay marks:** only two exist, "Loading the journal" and "Warming the viewer". The later warm tracks run after the server already says it is ready.

Test to run: `tests/test_it_boots.py`, the assertions after the warming test near line 1157.
