@volter/supercode-orchestrator 0.5.49 → 0.5.50

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.
package/board/cli.mjs CHANGED
@@ -17,6 +17,12 @@ import { openZtrackBoard } from './ztrack.mjs';
17
17
  import * as engine from './engine.mjs';
18
18
  import { runtimeDoor } from './runtime-door.mjs';
19
19
 
20
+ /** The messages on this machine the mailbox still has to deliver (`supercode message waiting`), by message id. */
21
+ function mailWaiting() {
22
+ const r = spawnSync(supercodeBin(), ['message', 'waiting', '--json'], { encoding: 'utf8', env: commandEnv(), timeout: 15_000 });
23
+ try { return new Map((JSON.parse(r.stdout) ?? []).map((mail) => [mail.id, mail])); } catch { return new Map(); }
24
+ }
25
+
20
26
  /**
21
27
  * The messages on this machine whose delivery the mailbox gave up on (`supercode message expired`), by message id:
22
28
  * filed by the board, never delivered within the mailbox's bound, kept unread. Empty when the mailbox does not answer.
@@ -843,11 +849,12 @@ export async function runWorkflow(argv) {
843
849
  const fleet = observeFleet(root);
844
850
  const publishing = boardPublishing(root);
845
851
  const expiredMail = mailExpiries();
852
+ const waitingMail = mailWaiting();
846
853
  const order = ['warning', 'error', 'critical'];
847
854
  const found = withBoard((b) => {
848
855
  const cards = args.task ? [engine.getTask(b.db, args.task)].filter(Boolean) : engine.listCards(b.db, {});
849
856
  return [...(args.task ? [] : engine.diagnosePublishing(publishing).map((d) => ({ task: '(board)', title_of_task: null, ...d }))),
850
- ...cards.flatMap((t) => engine.diagnose(b.db, t, { failureLimit: settings.failureLimit, fleet, launchWindowSeconds: settings.launchWindow, publishing, expiredMail }).map((d) => ({ task: t.id, title_of_task: t.title, ...d })))]
857
+ ...cards.flatMap((t) => engine.diagnose(b.db, t, { failureLimit: settings.failureLimit, fleet, launchWindowSeconds: settings.launchWindow, publishing, expiredMail, waitingMail }).map((d) => ({ task: t.id, title_of_task: t.title, ...d })))]
851
858
  .filter((d) => !args.severity || order.indexOf(d.severity) >= order.indexOf(args.severity));
852
859
  });
853
860
  if (args.json) { say(args, '', found); return 0; }
package/board/engine.mjs CHANGED
@@ -922,7 +922,7 @@ export function diagnosePublishing(publishing) {
922
922
  * same thing can go wrong, and supercode's own where only its sessions can): each `{ kind, severity, title, data,
923
923
  * actions }`, worst first.
924
924
  */
925
- export function diagnose(db, task, { failureLimit = DEFAULT_FAILURE_LIMIT, strandedSeconds = 30 * 60, blockedHours = 24, fleet = null, launchWindowSeconds = 300, publishing = null, expiredMail = null } = {}) {
925
+ export function diagnose(db, task, { failureLimit = DEFAULT_FAILURE_LIMIT, strandedSeconds = 30 * 60, blockedHours = 24, fleet = null, launchWindowSeconds = 300, publishing = null, expiredMail = null, waitingMail = null } = {}) {
926
926
  const out = [];
927
927
  const t = now();
928
928
  const events = all(db, 'SELECT kind, payload, created_at FROM task_events WHERE task_id = ? ORDER BY id', task.id);
@@ -983,13 +983,16 @@ export function diagnose(db, task, { failureLimit = DEFAULT_FAILURE_LIMIT, stran
983
983
  for (const a of (publishing?.abandoned ?? []).filter((a) => a.card === task.id).slice(0, 20)) {
984
984
  out.push({ kind: 'publication_abandoned', severity: 'warning', title: `its ${a.kind} (sequence ${a.sequence}) was not published to the team: refused ${a.attempts} times (${a.status} ${a.code ?? ''}): ${a.error}`, data: { publication: a.publication, sequence: a.sequence, status: a.status, code: a.code }, actions: [] });
985
985
  }
986
- // mail the board filed for the card whose delivery the mailbox gave up on (its wake expired): it stays unread there
987
- if (expiredMail?.size) {
986
+ // mail the board filed for the card that the mailbox still has to deliver (waiting), or gave up on (expired: it stays
987
+ // unread there)
988
+ if (expiredMail?.size || waitingMail?.size) {
989
+ const at = (ms) => new Date(ms).toISOString().replace(/\.\d+Z$/, 'Z');
988
990
  for (const row of all(db, "SELECT kind, payload FROM task_events WHERE task_id = ? AND kind IN ('notice_filed', 'session_notice_filed', 'actor_notice_filed', 'board_message_sent') ORDER BY id DESC LIMIT 200", task.id)) {
989
- const p = json(row.payload, {}) ?? {}, expiry = p.message_id && expiredMail.get(p.message_id);
990
- if (!expiry) continue;
991
+ const p = json(row.payload, {}) ?? {};
991
992
  const what = row.kind === 'notice_filed' ? `its ${p.kind} notice` : row.kind === 'board_message_sent' ? 'its board mail' : `its ${row.kind.replace('_filed', '').replace('_', ' ')}`;
992
- out.push({ kind: 'mail_expired', severity: 'warning', title: `${what} to ${expiry.to} was never delivered: ${expiry.reason} (${expiry.attempts} attempts); it stays unread in that mailbox`, data: { message_id: p.message_id, to: expiry.to, attempts: expiry.attempts, expired_at_ms: expiry.expired_at_ms }, actions: [] });
993
+ const expiry = p.message_id && expiredMail?.get(p.message_id), waiting = p.message_id && waitingMail?.get(p.message_id);
994
+ if (expiry) out.push({ kind: 'mail_expired', severity: 'warning', title: `${what} to ${expiry.to} was never delivered: ${expiry.reason} (${expiry.attempts} attempts); it stays unread in that mailbox`, data: { message_id: p.message_id, to: expiry.to, attempts: expiry.attempts, expired_at_ms: expiry.expired_at_ms }, actions: [] });
995
+ else if (waiting) out.push({ kind: 'mail_waiting', severity: 'warning', title: waiting.waiting_for ? `${what} to ${waiting.to} is waiting for ${waiting.waiting_for} since ${at(waiting.since_ms)} (offline)` : `${what} to ${waiting.to} is waiting since ${at(waiting.since_ms)}: ${waiting.last_error ?? 'not delivered yet'}`, data: { message_id: p.message_id, to: waiting.to, waiting_for: waiting.waiting_for, since_ms: waiting.since_ms }, actions: [] });
993
996
  }
994
997
  }
995
998
  const order = ['critical', 'error', 'warning'];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/supercode-orchestrator",
3
- "version": "0.5.49",
3
+ "version": "0.5.50",
4
4
  "type": "module",
5
5
  "description": "The orchestrator runtime over the Volter Harness ontology: one typed operational model whose folder is its serialization, read and written through the harness orchestration doors (docs/ORCHESTRATOR-IR.md)",
6
6
  "exports": {