@yemi33/minions 0.1.1859 → 0.1.1860

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/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.1860 (2026-05-10)
4
+
5
+ ### Fixes
6
+ - treat exit-0 + empty-result as phantom completion, retry instead of hard-failing PR contract (#2335)
7
+
3
8
  ## 0.1.1859 (2026-05-10)
4
9
 
5
10
  ### Features
@@ -2472,7 +2472,7 @@ const NON_TERMINAL_COMPLETION_STATUSES = new Set([
2472
2472
  'failed', 'failure', 'error',
2473
2473
  ]);
2474
2474
 
2475
- function detectNonTerminalResultSummary(_resultSummary, structuredCompletion, completionReport) {
2475
+ function detectNonTerminalResultSummary(_resultSummary, structuredCompletion, completionReport, opts) {
2476
2476
  const candidates = [completionReport?.status, structuredCompletion?.status];
2477
2477
  for (const status of candidates) {
2478
2478
  const norm = normalizeCompletionStatus(status);
@@ -2487,6 +2487,31 @@ function detectNonTerminalResultSummary(_resultSummary, structuredCompletion, co
2487
2487
  };
2488
2488
  }
2489
2489
  }
2490
+
2491
+ // Phantom completion (opt-in via opts.detectPhantom): process exited 0 but
2492
+ // the runtime never emitted any signal of what it actually did — no result-
2493
+ // event prose, no fenced ```completion block, no on-disk completion report.
2494
+ // This is the signature of a runtime CLI that crashed/aborted between session
2495
+ // start and result emission (token expiry, MCP daemon drop, sandbox crash).
2496
+ //
2497
+ // Before PR #2266 these silently fell through the slow stale-orphan path and
2498
+ // were retried. After #2266 the [process-exit] sentinel always lands, so
2499
+ // completeFromOutput now classifies them as SUCCESS — and without this branch
2500
+ // the PR-attachment contract hard-fails them with no retry.
2501
+ //
2502
+ // Only enabled at call sites where there is no other success signal (e.g.
2503
+ // engine/timeout.js completeFromOutput). runPostCompletionHooks has richer
2504
+ // signals (PRs created, plan-to-prd PRD file existence, autoRecover) and
2505
+ // must not be demoted by this heuristic.
2506
+ if (opts && opts.detectPhantom) {
2507
+ const summaryEmpty = !_resultSummary || !String(_resultSummary).trim();
2508
+ if (summaryEmpty && !structuredCompletion && !completionReport) {
2509
+ return {
2510
+ phrase: 'phantom-completion',
2511
+ reason: 'Phantom completion: process exited cleanly but the runtime emitted no result event, no structured completion, and no completion report — likely a runtime crash before result emission',
2512
+ };
2513
+ }
2514
+ }
2490
2515
  return null;
2491
2516
  }
2492
2517
 
package/engine/timeout.js CHANGED
@@ -307,7 +307,7 @@ function checkTimeouts(config) {
307
307
  outputResultSummary = parseAgentOutput(fullLogForHooks, runtimeName).resultSummary || '';
308
308
  const gateSummary = outputResultSummary || (!fullLogForHooks.includes('"type":') ? fullLogForHooks : '');
309
309
  completionDetection = isSuccess
310
- ? detectNonTerminalResultSummary(gateSummary, parseStructuredCompletion(fullLogForHooks, runtimeName), parseCompletionReportFile(item))
310
+ ? detectNonTerminalResultSummary(gateSummary, parseStructuredCompletion(fullLogForHooks, runtimeName), parseCompletionReportFile(item), { detectPhantom: true })
311
311
  : null;
312
312
  } catch (e) { log('warn', 'completion summary gate: ' + e.message); }
313
313
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.1859",
3
+ "version": "0.1.1860",
4
4
  "description": "Multi-agent AI dev team that runs from ~/.minions/ — five autonomous agents share a single engine, dashboard, and knowledge base",
5
5
  "bin": {
6
6
  "minions": "bin/minions.js"