Repository navigation
Description
🤖 Left by Claude Code, from the
/shiprun for #356 (branchfeat/boxd-in-app).
What happens
On a box made by BoxdHostDriver.create(), with nothing started on it, the agent's wakefulness classifier reports BUSY for minutes after the app connects. The app holds a BUSY box (correctly) and lets it go on the first IDLE reading, so the box stays awake and billed until the spell ends.
It is the cause of BoxdIntegrationTests.testAnIdleBoxStillSleepsWithTheAppAttached failing on 2026-10-07: the case gives the box 420 s to sleep with a 120 s idle timer, and the BUSY spell ate most of it. The case passed on f737dfa8 on 2026-10-06.
Three runs (boxd CLI v0.2.22 for the first, v0.2.23 after), every reading from the agent's status every 10 s:
| Run | BUSY from connect | Then |
|---|---|---|
| 1 (13:54 local) | ~5 min 24 s | IDLE, let go |
| 2 (14:33) | ~5 min | IDLE, let go |
| 3 (14:57) | > 7 min (whole window) | never IDLE in the test |
| 4 (15:16) | ~2 min 42 s | IDLE, let go |
Every BUSY reading was verdict=BUSY classifier=BUSY running=true stalled=false asserting=true. The reply's cpu_fraction is the agent thread's own CPU (thread_cpu_fraction), ~0.0014, so it says nothing about the box's load.
What it is not
ps -eo pid,ppid,stat,etimes,wchan,comm,args and sudo ss -tpn state established on the app-created box, once a minute while it read BUSY (run 4):
wr-agent serveandwr-agent relay: excluded (EXCLUDED_SELF_ONLY), and asleep (hrtimer_nanosleep,do_poll).boxd-automations daemon: excluded; its TCP connection to10.39.0.1:9002was gone by 14:19./bin/sh -c 'wr-agent' relay --socket …(ppid 0, the app's service connection): the only counted process, with no TCP connection, no timer and no CPU, and still alive when the box went IDLE.- A
sleep 10(ppid 1) in the first sample only. - TCP: only connections to boxd's ssh port 57073, owned by no counted process.
- The heartbeat is a 1-byte datagram a minute, far under the 500 B/s
netthreshold.
A plain boxd machine new box sampled the same way for 5 minutes ran systemd-tmpfiles --clean and a logrotate in its first second, then nothing counted: no apt-daily, no unattended-upgrades.
So no counted process holds a socket, a timer or CPU. What is left are the signals ps/ss cannot see:
lifecycle:crate::vcs::is_busy()(wakefulness.rs, the service loop'sclassifier.step(&s, crate::vcs::is_busy())), true while any VCS, File or Layout request holds aPermit. An app request held open on a fresh box would hold it BUSY for as long as it runs.net: the box's whole non-loopback traffic (/proc/net/dev) against 500 B/s over the window, which counts the app's own traffic: the agent push at connect, the status polls, ssh keepalives.pty/ input: unlikely, no panes in the test.
Next step
Make the vote visible: add the last tick's features (cpu, d_state, timer, socket, net, pty_rate, since_input, lifecycle, and the in-flight permit count) to the status reply as a debug field, rebuild the Linux agent, and rerun the case once with the app logging them. Then fix whichever signal it is (for lifecycle, find the request that stays in flight; for net, whether the app's own traffic should count).
Until then, testAnIdleBoxStillSleepsWithTheAppAttached is flaky on a fresh box, and #356 ships with it as a named risk.
Activity
joelmoss commentedon Oct 7, 2026
Closing as wontfix: a fresh box reads BUSY for a few minutes once, right after creation, when it is normally about to be used anyway. In 3 of 4 runs it then went IDLE with the app still attached, so the app is not keeping its own boxes awake. The flaky
testAnIdleBoxStillSleepsWithTheAppAttachedshould be fixed in the test (a longer window, or let the box settle before the idle timer). Reopen if a box is ever seen BUSY past ~15 minutes.🤖 Left by Claude Code