Skip to content

Resume the ops engine after an out-of-band reset recovery #53

Description

@mabry1985

Gap

After a universe wipe, if re-registration lands out-of-band (the agent's own st_register / st_recover_token retry) rather than through the supervisor's _recover, nothing restarts the ops engine — it stays stopped and the fleet earns nothing until a manual st_autopilot_start.

start_ops is only reachable from:

  • __init__.py surface-start resume — fires only on a full agent boot, not on a hot reload (a reload re-runs register() but not the surface lifecycle), and
  • the manual st_autopilot_start tool.

reset_recovered has a single subscriber (_epoch_clear), which only drops epoch-scoped state — it does not resume ops. And that event is emitted only by _recover; the agent's st_register path emits nothing.

Evidence (live 2026-07-05 wipe)

Engine stopped at the wipe; registration recovered ~5 min later via the agent's st_register retry (300s backoff), but the ops supervisor never came back. Fleet sat idle ~24 min until a manual start over A2A.

Note

v2.9.2 (#52) makes _recover ride out the wipe in-loop (bounded 503 retry), so in the common case the supervisor never stops and this backstop rarely triggers. This issue covers the tail: _recover's retry budget exhausted, or the agent racing ahead and claiming the call sign first (then _recover sees "already claimed" and stops despite a now-valid token).

Proposed fix

On a successful reset recovery from any path, resume ops if fleet.autopilot_intended() and the engine isn't already running:

  • have recover_from_reset / st_register success emit reset_recovered (or a new agent_reregistered), and
  • add a subscriber that calls start_ops(window_minutes) when intended + not running.
  • Also: in _recover, treat "already claimed" as recovered if a live GET /my/agent with the current token succeeds (claimed by us), so the agent-wins-the-race case doesn't stop the engine.

Layering note: keep the client→fleet dependency out of client.py; wire the resume via the event bus in __init__.py.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions