/// ops_heal.mbt —— no_signal 看护恢复(M4 运维:AO watchdog 语义)
///
/// 语义参考 agent-orchestrator 的 `no_signal` watchdog(长时间静默 -> 视作 broken):
/// 心跳超时(或从未上报)且处于"执行中/已领取/拆分中"的任务,回滚为"已领取"
/// 以便重新认领/重派(claim 状态机天然支持 Pending->Claimed/Claimed->Executing),
/// 并清掉其心跳记录,完成"回滚重派"闭环。原子/已完成/已归档任务不在看护范围。

/// 看护一轮:扫描引擎全部任务,对心跳超时静默的活跃任务执行回滚。
/// 返回本轮被回滚(重派)的任务 id 列表。
pub fn heal_stale_tasks(
  engine : FistEngine,
  hb : Heartbeat,
  now : String,
  timeout_sec~ : Int = 600,
) -> Result[Array[String], String] {
  let healed : Array[String] = []
  for t in engine.list_all() {
    let st = t.get_status()
    let stale = (st.to_string() == "执行中" || st.to_string() == "已领取" || st.to_string() == "拆分中") &&
      hb.is_stale(t.get_id(), now, timeout_sec=timeout_sec)
    if stale {
      // 回滚为已领取(reopen_task 内部更新 updated_at)
      match engine.reopen_task(t.get_id(), now) {
        Ok(_) => {
          hb.clear(t.get_id())
          healed.push(t.get_id())
        }
        Err(e) => return Err(e)
      }
    }
  }
  Ok(healed)
}