squadrant 0.13.2 → 0.13.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -544,6 +544,9 @@ function reduce(rec, ev, now) {
544
544
  case "task.reattached":
545
545
  return stampAttempt(base, {}, now);
546
546
  case "task.first-turn.confirmed":
547
+ if (rec.firstTurnConfirmedAt) {
548
+ return { ...rec, lastEvent: "task.progress" };
549
+ }
547
550
  return { ...rec, firstTurnConfirmedAt: now, lastEvent: ev.type };
548
551
  case "task.stalled":
549
552
  case "task.idle":
@@ -860,6 +863,25 @@ function createDaemon(deps) {
860
863
  continue;
861
864
  }
862
865
  }
866
+ if (r.mode === "interactive" && r.state === "submitted" && !r.firstTurnConfirmedAt) {
867
+ const elapsed = t - r.lastHeartbeat;
868
+ if (elapsed > r.heartbeatBudgetMs) {
869
+ if (deps.notify && quietNotifiedAt.get(r.id) !== r.lastHeartbeat) {
870
+ quietNotifiedAt.set(r.id, r.lastHeartbeat);
871
+ const tag = crewTag(r);
872
+ const synthEvent = { type: "task.quiet", id: r.id, quietMs: elapsed };
873
+ const message = `\u26A0\uFE0F CREW UNDELIVERED ${tag}: first turn may not have landed (crew never started) \u2014 re-send the task or check the spawn.`;
874
+ try {
875
+ const p = deps.notify({ project: r.project, message, record: r, event: synthEvent });
876
+ if (p && typeof p.catch === "function")
877
+ p.catch(() => {
878
+ });
879
+ } catch {
880
+ }
881
+ }
882
+ continue;
883
+ }
884
+ }
863
885
  const idle = evaluateStall(r, t);
864
886
  if (idle) {
865
887
  store.put(idle);