# Real-server lifecycle evidence

AI-assisted; verified with the tests and tools listed above.

Both checkouts were installed with `vp i` and independently bundled with
`vp run --filter t3 build:bundle`. The driver launches each checkout's real
`apps/server/dist/bin.mjs`; it does not import services, replace dependencies,
or mock the daemon. No tests were used as evidence.

Environment for both captures: Linux x86_64, Node 26.12.1, agent-device 0.21.31,
expo-device-hub 0.19.1, fresh databases created by each server, identical settings
written through authenticated WebSocket RPC. No copied database, device lease,
booted emulator, remote daemon, or live application state. Local Android SDK
platform-tools, emulator executable, and command-line tools permit discovery
of an empty device inventory. Home and ADB endpoints are isolated by the driver.
The dev URL enables reusable development authentication; no browser is involved.

Both terminal recordings are 1280 x 760 at 10 fps, black text on white.
Each accompanying PNG is the final terminal output, captured only after two
screenshots 500 ms apart had zero differing pixels. The recordings were decoded
and their progression inspected, and both final screenshots inspected before
upload. Private paths and pairing credentials are omitted from auxiliary logs.

## Reproduce

Install Python `websocket-client` (1.9.2 used here). Put `lifecycle.py`, `record.sh`,
and a Python dependency directory named `deps` in a scratch directory. The scratch
directory needs an Android SDK in `sdk` and Java 21 in `jdk`.
The SDK used command-line tools release 13114758 and installed `platform-tools`
and `emulator` through sdkmanager; no system image is needed.

Run once for each built checkout, with a different side label:

```sh
headless-desktop bash record.sh CHECKOUT SCRATCH before
headless-desktop bash record.sh OTHER_CHECKOUT SCRATCH after
```

The driver generates a new output directory and fresh checkout-local state on
every invocation. It creates a random development credential without displaying
it. No pre-existing project, thread, or account is needed.

## Identical scripted interaction

1. Start the real built server. Enable local device support and agent access with
   `device.configure`, then call `device.list` with `retryHostId: "local"`.
   This executes the application's real agent-tool readiness path and starts
   its pinned agent-device daemon. Record the daemon PID and process start time
   from the environment's state and verify its HTTP health endpoint.
2. SIGKILL only the server PID captured at spawn. Verify the recorded daemon is
   still the same live process and its health endpoint still answers.
3. Restart the same build with the same state. Authenticate RPC without invoking
   any device operation or initializing agent tools. SIGTERM that server and
   await its exit. After three seconds, inspect the same daemon PID/start time
   and HTTP health endpoint.
4. Stop any surviving daemon through its installed CLI as scenario cleanup.
   Start another server in the same environment, initialize a new daemon through
   the same RPC sequence, SIGKILL that server, and verify daemon survival.
5. Restart with the same state without using device tools. Call
   `device.configure` with `agentAccessEnabled: false`, the server operation
   used by Devices settings. After its response and three seconds, inspect the
   same daemon PID/start time and HTTP health endpoint. Gracefully stop the server.
6. Clean up only recorded servers, hubs, daemons, and the isolated ADB server.

Observed on base: the daemon remained alive and HTTP-healthy in both cases.
Observed on head: the daemon stopped and HTTP health was unavailable in both.
The abrupt-kill survival check succeeded in all four scenarios.

The auxiliary raw server log for the first restart is superseded by the second
restart because both have the same label; the uninterrupted recordings and
transcripts retain both complete scenarios. The driver logs real process IDs,
not a synthesized expected result, and excludes zombies and PID reuse.

Not exercised: desktop shell quit, clicking the Settings UI, non-Linux hosts,
older-version CLI selection, missing-version fallback, dead/malformed daemon
records, or missing installed tools. These captures focus on the reported real
server lifecycle with the current pin.
