| index dd633b61a..2ed702bc6 100644 |
| --- a/internal/console/apicli.go |
| +++ b/internal/console/apicli.go |
| @@ -470,11 +470,19 @@ func (s *Server) handleAPIRollback(w http.ResponseWriter, r *http.Request) { |
| } |
| |
| // handleAPIRestart answers `carlos restart`: touch the app's restart |
| -// generation so every box serving it cycles that app's processes within |
| -// seconds (issue #113). No version moves, no config is written, no bake window |
| -// applies — this is the member-facing way to cycle a wedged instance, which |
| -// until now meant a box login the platform's own design rule forbids ("every |
| -// carlos command works for a user with zero infra access"). |
| +// generation, then bump the serial so every box serving it cycles that app's |
| +// processes within seconds (issue #113). No version moves, no config is |
| +// written, no bake window applies — this is the member-facing way to cycle a |
| +// wedged instance, which until now meant a box login the platform's own design |
| +// rule forbids ("every carlos command works for a user with zero infra |
| +// access"). |
| +// |
| +// The BUMP is the delivery mechanism, not decoration. Boxes do not poll |
| +// restart generations: the agent's existing 2s serial poll is what makes it |
| +// look, exactly as with a promote or a config write (internal/host/restart.go). |
| +// A touch that landed without a bump would still converge — on the hourly root |
| +// pass, up to an hour later — which is the floor, not the promise this door |
| +// makes. |
| // |
| // The doors, in order, and why this order — handleAPITrashApp's exactly: |
| // |
| @@ -537,9 +545,10 @@ func (s *Server) handleAPIRestart(w http.ResponseWriter, r *http.Request) { |
| return |
| } |
| s.audit(acct, app, addr, "restart", "requested a restart (cli)") |
| - // The request is in the bucket; this is what makes boxes look NOW rather |
| - // than on the hourly floor — the difference between "seconds" and "up to |
| - // an hour" for the one verb people type when something is stuck. |
| + // The request is in the bucket; this is what makes boxes LOOK at it — they |
| + // read restart generations only when the serial moves. The difference |
| + // between "seconds" and "up to an hour" for the one verb people type when |
| + // something is stuck. |
| s.bumpSerial(ctx) |
| writeJSON(w, http.StatusOK, map[string]any{ |
| "requested": true, "account": acct.Sqid, "app": app, |