A box actively serving requests through its preview URL is idle-stopped at last SDK call + autoStop, as if the preview traffic never happened. Only SDK calls count as activity, contradicting the documented behaviour that "Preview URL traffic keeps a running box alive".
Reproduction
Create a box with autoStop=1 (60s), start a server on a port, then poll its external preview URL every 15s with zero further SDK calls:
T=15s external GET=200 boxState=running
T=30s external GET=200 boxState=running
T=45s external GET=200 boxState=stopping <- already stopping despite continuous 200s
T=60s external GET=502 boxState=stopped
The box stops at exactly last SDK call + 60s. A zero-access control box with the same autoStop also stops after its window, so idle-stop itself works — the defect is that external traffic is not recorded as activity.
Cause
The proxy does renew on every proxied request, but POST /box/{id}/last-activity sits on BoxController, whose class-level OrganizationResourceActionGuard runs before the route's own OrGuard([BoxAccessGuard, ProxyGuard, RegionBoxAccessGuard]). That guard exempts only a runner context, so a proxy context — which carries no organization by design — falls through to an organization check it can never satisfy, and every renewal returns 403.
Separately, CONNECT tunnels never renew activity at all, so a long-lived tunnel stream does not keep its box alive either.
Expected
A running box reached through its preview URL or a CONNECT tunnel, with no SDK calls, is not idle-stopped while the traffic continues. A box with no access still stops after its autoStop window.
Linear: POL-326
A box actively serving requests through its preview URL is idle-stopped at
last SDK call + autoStop, as if the preview traffic never happened. Only SDK calls count as activity, contradicting the documented behaviour that "Preview URL traffic keeps a running box alive".Reproduction
Create a box with
autoStop=1(60s), start a server on a port, then poll its external preview URL every 15s with zero further SDK calls:The box stops at exactly
last SDK call + 60s. A zero-access control box with the sameautoStopalso stops after its window, so idle-stop itself works — the defect is that external traffic is not recorded as activity.Cause
The proxy does renew on every proxied request, but
POST /box/{id}/last-activitysits onBoxController, whose class-levelOrganizationResourceActionGuardruns before the route's ownOrGuard([BoxAccessGuard, ProxyGuard, RegionBoxAccessGuard]). That guard exempts only a runner context, so a proxy context — which carries no organization by design — falls through to an organization check it can never satisfy, and every renewal returns 403.Separately, CONNECT tunnels never renew activity at all, so a long-lived tunnel stream does not keep its box alive either.
Expected
A running box reached through its preview URL or a CONNECT tunnel, with no SDK calls, is not idle-stopped while the traffic continues. A box with no access still stops after its
autoStopwindow.Linear: POL-326