@flowdesk/opencode-plugin 0.1.14 → 0.1.15

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.
Files changed (55) hide show
  1. package/README.md +1 -1
  2. package/dist/agent-task-output.d.ts +12 -0
  3. package/dist/agent-task-output.d.ts.map +1 -1
  4. package/dist/agent-task-output.js +110 -4
  5. package/dist/agent-task-output.js.map +1 -1
  6. package/dist/agent-task-runner.d.ts +12 -1
  7. package/dist/agent-task-runner.d.ts.map +1 -1
  8. package/dist/agent-task-runner.js +237 -16
  9. package/dist/agent-task-runner.js.map +1 -1
  10. package/dist/completion-ui-cache.d.ts.map +1 -1
  11. package/dist/completion-ui-cache.js +159 -29
  12. package/dist/completion-ui-cache.js.map +1 -1
  13. package/dist/event-hook-observer.d.ts.map +1 -1
  14. package/dist/event-hook-observer.js +66 -2
  15. package/dist/event-hook-observer.js.map +1 -1
  16. package/dist/managed-dispatch-adapter.d.ts +62 -0
  17. package/dist/managed-dispatch-adapter.d.ts.map +1 -1
  18. package/dist/managed-dispatch-adapter.js +465 -1
  19. package/dist/managed-dispatch-adapter.js.map +1 -1
  20. package/dist/model-selection-engine.d.ts +15 -2
  21. package/dist/model-selection-engine.d.ts.map +1 -1
  22. package/dist/model-selection-engine.js +109 -42
  23. package/dist/model-selection-engine.js.map +1 -1
  24. package/dist/provider-usage-live-tool.d.ts.map +1 -1
  25. package/dist/provider-usage-live-tool.js +135 -33
  26. package/dist/provider-usage-live-tool.js.map +1 -1
  27. package/dist/server.d.ts +1 -0
  28. package/dist/server.d.ts.map +1 -1
  29. package/dist/server.js +52 -3
  30. package/dist/server.js.map +1 -1
  31. package/dist/stall-recovery.d.ts +4 -3
  32. package/dist/stall-recovery.d.ts.map +1 -1
  33. package/dist/stall-recovery.js +245 -25
  34. package/dist/stall-recovery.js.map +1 -1
  35. package/dist/status-live-tool.d.ts.map +1 -1
  36. package/dist/status-live-tool.js +1 -0
  37. package/dist/status-live-tool.js.map +1 -1
  38. package/dist/tui-subtask-activity.d.ts +4 -0
  39. package/dist/tui-subtask-activity.d.ts.map +1 -1
  40. package/dist/tui-subtask-activity.js +29 -24
  41. package/dist/tui-subtask-activity.js.map +1 -1
  42. package/dist/tui-usage-snapshot.d.ts.map +1 -1
  43. package/dist/tui-usage-snapshot.js +92 -6
  44. package/dist/tui-usage-snapshot.js.map +1 -1
  45. package/dist/tui.d.ts.map +1 -1
  46. package/dist/tui.js +43 -16
  47. package/dist/tui.js.map +1 -1
  48. package/dist/workflow-assign-tool.d.ts.map +1 -1
  49. package/dist/workflow-assign-tool.js +21 -3
  50. package/dist/workflow-assign-tool.js.map +1 -1
  51. package/dist/workflow-dispatch-tool.d.ts +12 -0
  52. package/dist/workflow-dispatch-tool.d.ts.map +1 -1
  53. package/dist/workflow-dispatch-tool.js +24 -26
  54. package/dist/workflow-dispatch-tool.js.map +1 -1
  55. package/package.json +2 -2
@@ -161,6 +161,7 @@ export declare function backfillTerminalAgentTaskFailedLanesV1(input: {
161
161
  rootDir: string;
162
162
  workflowId: string;
163
163
  now?: Date;
164
+ refreshCompletionUiCaches?: boolean;
164
165
  }): FlowDeskAgentTaskTerminalBackfillResultV1;
165
166
  /**
166
167
  * On startup/reload: any `pending_retry_plan` in `launched` state with no matching
@@ -230,9 +231,9 @@ export interface FlowDeskChildSessionMonitorResultV1 {
230
231
  * Called from the watchdog cycle once per interval:
231
232
  * - Poll session.messages for each running child session
232
233
  * - On result: write task_result evidence + terminal lifecycle
233
- * - At 20s silence: nudge with noReply: true
234
- * - At 40s: second nudge
235
- * - At 60s+: session.abort + task_failed + terminal lifecycle
234
+ * - At 10s silence: nudge with noReply: true
235
+ * - At 20s: second nudge
236
+ * - At 30s+: session.abort + task_failed + terminal lifecycle
236
237
  */
237
238
  export declare function monitorChildSessionsV1(input: {
238
239
  rootDir: string;
@@ -1 +1 @@
1
- {"version":3,"file":"stall-recovery.d.ts","sourceRoot":"","sources":["../src/stall-recovery.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stall-recovery.d.ts","sourceRoot":"","sources":["../src/stall-recovery.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { applyFlowDeskSessionEvidenceWriteIntentsV1, prepareFlowDeskSessionEvidenceWriteIntentV1, reloadFlowDeskSessionEvidenceV1, projectFlowDeskLaneStallV1, } from "@flowdesk/core";
1
+ import { applyFlowDeskSessionEvidenceWriteIntentsV1, prepareFlowDeskSessionEvidenceWriteIntentV1, reloadFlowDeskSessionEvidenceV1, projectFlowDeskLaneStallV1, validateTopTierReviewVerdictV1, } from "@flowdesk/core";
2
2
  import { createHmac, createHash, timingSafeEqual, randomBytes } from "node:crypto";
3
3
  import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
4
4
  import { join } from "node:path";
@@ -254,6 +254,11 @@ export function validateAndAbortFlowDeskLaneEvidenceV1(input) {
254
254
  entry.record.state === "aborted");
255
255
  if (!persisted)
256
256
  return { status: "write_failed", reason: "abort_evidence_not_persisted" };
257
+ refreshFlowDeskCompletionUiCachesV1({
258
+ rootDir: input.rootDir,
259
+ workflowId: input.workflow_id,
260
+ observedAt: observedAt,
261
+ });
257
262
  return {
258
263
  status: "aborted",
259
264
  lane_id: input.lane_id,
@@ -582,6 +587,14 @@ export function backfillTerminalAgentTaskFailedLanesV1(input) {
582
587
  terminalEvidenceIds.push(evidenceId);
583
588
  }
584
589
  }
590
+ if ((input.refreshCompletionUiCaches ?? true) &&
591
+ (terminalEvidenceIds.length > 0 || latestFailure.size > 0)) {
592
+ refreshFlowDeskCompletionUiCachesV1({
593
+ rootDir: input.rootDir,
594
+ workflowId: input.workflowId,
595
+ observedAt,
596
+ });
597
+ }
585
598
  return {
586
599
  status: "backfill_completed",
587
600
  workflowId: input.workflowId,
@@ -1314,7 +1327,7 @@ async function pollChildSessionOutput(client, childSessionId, messagesTimeoutMs
1314
1327
  return null;
1315
1328
  const observed = observeFlowDeskAgentTaskOutputV1(raw);
1316
1329
  if (observed.terminalObserved && observed.latestText !== undefined && observed.latestText.trim().length > 0)
1317
- return { text: observed.latestText, completionStatus: "final", outputKind: observed.outputKind, usableForSynthesis: observed.usableForSynthesis };
1330
+ return { text: observed.latestText, completionStatus: "final", outputKind: observed.outputKind, usableForSynthesis: observed.usableForSynthesis, looksLikeRefusalOrError: observed.looksLikeRefusalOrError };
1318
1331
  return null;
1319
1332
  }
1320
1333
  catch {
@@ -1340,7 +1353,7 @@ async function pollChildSessionCandidate(client, childSessionId, messagesTimeout
1340
1353
  return null;
1341
1354
  const observed = observeFlowDeskAgentTaskOutputV1(raw);
1342
1355
  if (observed.latestText !== undefined && observed.latestText.trim().length > 0)
1343
- return { text: observed.latestText, completionStatus: observed.terminalObserved ? "final" : "partial", outputKind: observed.outputKind, usableForSynthesis: observed.usableForSynthesis };
1356
+ return { text: observed.latestText, completionStatus: observed.terminalObserved ? "final" : "partial", outputKind: observed.outputKind, usableForSynthesis: observed.usableForSynthesis, looksLikeRefusalOrError: observed.looksLikeRefusalOrError };
1344
1357
  return null;
1345
1358
  }
1346
1359
  catch {
@@ -1386,6 +1399,91 @@ function writeChildSessionEvidence(rootDir, workflowId, evidenceId, record) {
1386
1399
  const applied = applyFlowDeskSessionEvidenceWriteIntentsV1(rootDir, [prepared.writeIntent]);
1387
1400
  return applied.ok && applied.writtenPaths.length > 0;
1388
1401
  }
1402
+ function extractJsonBlocksFromText(raw) {
1403
+ const trimmed = raw.trim();
1404
+ const results = [];
1405
+ if (trimmed.startsWith("{") && trimmed.endsWith("}"))
1406
+ return [trimmed];
1407
+ const fencePattern = /```(?:json)?\s*\n?(\{[\s\S]*?\})\s*\n?```/g;
1408
+ for (const match of trimmed.matchAll(fencePattern)) {
1409
+ if (match[1])
1410
+ results.push(match[1].trim());
1411
+ }
1412
+ if (results.length > 0)
1413
+ return results;
1414
+ let depth = 0;
1415
+ let start = -1;
1416
+ let lastBlock;
1417
+ for (let i = 0; i < trimmed.length; i++) {
1418
+ const ch = trimmed[i];
1419
+ if (ch === "{") {
1420
+ if (depth === 0)
1421
+ start = i;
1422
+ depth++;
1423
+ }
1424
+ else if (ch === "}") {
1425
+ depth--;
1426
+ if (depth === 0 && start !== -1) {
1427
+ lastBlock = trimmed.slice(start, i + 1).trim();
1428
+ start = -1;
1429
+ }
1430
+ }
1431
+ }
1432
+ return lastBlock === undefined ? [] : [lastBlock];
1433
+ }
1434
+ function observedTopTierReviewerVerdictFromText(input) {
1435
+ for (const block of extractJsonBlocksFromText(input.text)) {
1436
+ try {
1437
+ const candidate = JSON.parse(block);
1438
+ const validation = validateTopTierReviewVerdictV1(candidate);
1439
+ if (!validation.ok)
1440
+ continue;
1441
+ const verdict = candidate;
1442
+ if (verdict.workflow_id === input.workflowId)
1443
+ return verdict;
1444
+ }
1445
+ catch {
1446
+ // Keep scanning candidates.
1447
+ }
1448
+ }
1449
+ return undefined;
1450
+ }
1451
+ function persistObservedReviewerVerdict(input) {
1452
+ const evidenceId = input.verdict.verdict_id;
1453
+ if (!writeChildSessionEvidence(input.rootDir, input.workflowId, evidenceId, input.verdict))
1454
+ return false;
1455
+ const reloaded = reloadFlowDeskSessionEvidenceV1({ rootDir: input.rootDir, workflowId: input.workflowId });
1456
+ return reloaded.ok && reloaded.blocked.length === 0 && reloaded.entries.some((entry) => entry.evidenceClass === "reviewer_verdict" &&
1457
+ entry.evidenceId === evidenceId &&
1458
+ entry.record.verdict_id === input.verdict.verdict_id);
1459
+ }
1460
+ function writeAgentTaskCompleteLifecycleForVerdict(input) {
1461
+ return writeChildSessionEvidence(input.rootDir, input.workflowId, `lifecycle-agent-task-complete-${input.laneId}-${input.verdictId}`, {
1462
+ schema_version: "flowdesk.lane_lifecycle_record.v1",
1463
+ lane_id: input.laneId,
1464
+ workflow_id: input.workflowId,
1465
+ attempt_id: input.attemptId,
1466
+ parent_session_ref: input.parentSessionRef,
1467
+ child_session_ref: input.childSessionId.startsWith("ses-") ? input.childSessionId : `ses-${input.childSessionId}`,
1468
+ message_ref: `msg-${input.laneId}`,
1469
+ agent_ref: input.agentRef,
1470
+ provider_qualified_model_id: input.providerQualifiedModelId,
1471
+ state: "complete",
1472
+ verdict_ref: input.verdictId,
1473
+ output_ref: `output-${input.taskResultEvidenceId}`,
1474
+ runtime_echo_ref: `runtime-echo-${input.laneId}`,
1475
+ telemetry_ref: `telemetry-${input.laneId}`,
1476
+ timeout_ms: 0,
1477
+ orphan_max_age_ms: 0,
1478
+ retry_count: 0,
1479
+ created_at: input.observedAt,
1480
+ updated_at: input.observedAt,
1481
+ dispatch_authority_enabled: false,
1482
+ providerCall: false,
1483
+ actualLaneLaunch: false,
1484
+ runtimeExecution: false,
1485
+ });
1486
+ }
1389
1487
  function laneAlreadyHasTerminalTaskEvidence(input) {
1390
1488
  const reloaded = reloadFlowDeskSessionEvidenceV1({
1391
1489
  rootDir: input.rootDir,
@@ -1400,6 +1498,64 @@ function laneAlreadyHasTerminalTaskEvidence(input) {
1400
1498
  return record.lane_id === input.laneId;
1401
1499
  });
1402
1500
  }
1501
+ function terminalEvidenceObservedAtMs(record) {
1502
+ const value = typeof record.updated_at === "string"
1503
+ ? record.updated_at
1504
+ : typeof record.created_at === "string"
1505
+ ? record.created_at
1506
+ : typeof record.observed_at === "string"
1507
+ ? record.observed_at
1508
+ : undefined;
1509
+ const parsed = value === undefined ? Number.NaN : Date.parse(value);
1510
+ return Number.isFinite(parsed) ? parsed : 0;
1511
+ }
1512
+ function chooseLaterTerminalEndState(existing, candidate) {
1513
+ if (existing === undefined)
1514
+ return candidate;
1515
+ if (candidate.observedAtMs > existing.observedAtMs)
1516
+ return candidate;
1517
+ if (candidate.observedAtMs < existing.observedAtMs)
1518
+ return existing;
1519
+ // Prefer task_result for equal timestamps; otherwise keep the existing entry so
1520
+ // duplicate event-session-error / failed-child evidence is idempotent.
1521
+ return candidate.hasTaskResult && !existing.hasTaskResult ? candidate : existing;
1522
+ }
1523
+ function collectTerminalLaneEndStatesV1(entries) {
1524
+ const terminalByLane = new Map();
1525
+ for (const entry of entries) {
1526
+ const rec = entry.record;
1527
+ const laneId = typeof rec.lane_id === "string" ? rec.lane_id : undefined;
1528
+ if (laneId === undefined)
1529
+ continue;
1530
+ let state;
1531
+ let hasTaskResult = false;
1532
+ if (entry.evidenceClass === "lane_lifecycle") {
1533
+ state = typeof rec.state === "string" && TERMINAL_LANE_STATES.has(rec.state) ? rec.state : undefined;
1534
+ }
1535
+ else if (entry.evidenceClass === "task_result") {
1536
+ state = "complete";
1537
+ hasTaskResult = true;
1538
+ }
1539
+ else if (entry.evidenceClass === "task_failed") {
1540
+ state = rec.failure_category === "no_response" ? "no_output" : "invocation_failed";
1541
+ }
1542
+ if (state === undefined)
1543
+ continue;
1544
+ terminalByLane.set(laneId, chooseLaterTerminalEndState(terminalByLane.get(laneId), {
1545
+ laneId,
1546
+ state,
1547
+ observedAtMs: terminalEvidenceObservedAtMs(rec),
1548
+ hasTaskResult,
1549
+ }));
1550
+ }
1551
+ return terminalByLane;
1552
+ }
1553
+ function latestTerminalObservedAtIso(endStates, fallbackMs) {
1554
+ let latest = 0;
1555
+ for (const state of endStates)
1556
+ latest = Math.max(latest, state.observedAtMs);
1557
+ return new Date(latest > 0 ? latest : fallbackMs).toISOString();
1558
+ }
1403
1559
  function childProgressLabel(value) {
1404
1560
  const compact = value.replace(/\s+/g, " ").trim();
1405
1561
  return compact.length > 120 ? `${compact.slice(0, 119)}…` : compact;
@@ -1427,15 +1583,15 @@ function writeAgentTaskProgressEvidence(input) {
1427
1583
  * Called from the watchdog cycle once per interval:
1428
1584
  * - Poll session.messages for each running child session
1429
1585
  * - On result: write task_result evidence + terminal lifecycle
1430
- * - At 20s silence: nudge with noReply: true
1431
- * - At 40s: second nudge
1432
- * - At 60s+: session.abort + task_failed + terminal lifecycle
1586
+ * - At 10s silence: nudge with noReply: true
1587
+ * - At 20s: second nudge
1588
+ * - At 30s+: session.abort + task_failed + terminal lifecycle
1433
1589
  */
1434
1590
  export async function monitorChildSessionsV1(input) {
1435
1591
  const nowMs = (input.now ?? new Date()).getTime();
1436
- const nudgeQuietPeriodMs = input.nudgeQuietPeriodMs ?? 20_000;
1592
+ const nudgeQuietPeriodMs = input.nudgeQuietPeriodMs ?? 10_000;
1437
1593
  const maxNudges = input.maxNudges ?? 2;
1438
- const abortThresholdMs = input.abortThresholdMs ?? 60_000;
1594
+ const abortThresholdMs = input.abortThresholdMs ?? 30_000;
1439
1595
  const result = { lanesPolled: 0, lanesCompleted: 0, lanesNudged: 0, lanesAborted: 0 };
1440
1596
  const reloaded = reloadFlowDeskSessionEvidenceV1({ rootDir: input.rootDir, workflowId: input.workflowId });
1441
1597
  if (!reloaded.ok)
@@ -1445,9 +1601,12 @@ export async function monitorChildSessionsV1(input) {
1445
1601
  .filter(e => e.evidenceClass === "agent_task_child_session")
1446
1602
  .map(e => e.record)
1447
1603
  .filter(r => r.schema_version === AGENT_TASK_CHILD_SESSION_SCHEMA_VERSION);
1448
- // Find lanes that are NOT yet terminal (by lifecycle state or by task_result/task_failed evidence)
1449
- const terminalLaneIds = new Set();
1450
- const terminalTaskResultLaneIds = new Set();
1604
+ // Find lanes that are NOT yet terminal. Terminal evidence can come from
1605
+ // task_result, task_failed (including event-session-error records), or a
1606
+ // lifecycle terminal state. The map keeps the extracted end-state timestamp so
1607
+ // cache refreshes are monotonic/idempotent even when no task_result exists.
1608
+ const terminalEndStates = collectTerminalLaneEndStatesV1(reloaded.entries);
1609
+ const terminalLaneIds = new Set(terminalEndStates.keys());
1451
1610
  const awaitingPermissionLaneIds = new Set();
1452
1611
  const latestProgressByLane = new Map();
1453
1612
  for (const entry of reloaded.entries) {
@@ -1463,17 +1622,8 @@ export async function monitorChildSessionsV1(input) {
1463
1622
  latestProgressByLane.set(laneIdVal, { observedAtMs, phase });
1464
1623
  }
1465
1624
  }
1466
- if (entry.evidenceClass === "lane_lifecycle") {
1467
- const s = rec.state;
1468
- if (s === "complete" || s === "invocation_failed" || s === "no_output" || s === "incomplete")
1469
- terminalLaneIds.add(laneIdVal);
1470
- }
1471
- else if (entry.evidenceClass === "task_result" || entry.evidenceClass === "task_failed") {
1472
- terminalLaneIds.add(laneIdVal);
1473
- if (entry.evidenceClass === "task_result")
1474
- terminalTaskResultLaneIds.add(laneIdVal);
1475
- }
1476
1625
  }
1626
+ const terminalRefreshObservedAt = latestTerminalObservedAtIso(terminalEndStates.values(), nowMs);
1477
1627
  for (const [laneId, progress] of latestProgressByLane) {
1478
1628
  if (progress.phase === "awaiting_permission")
1479
1629
  awaitingPermissionLaneIds.add(laneId);
@@ -1490,18 +1640,26 @@ export async function monitorChildSessionsV1(input) {
1490
1640
  if (rec.phase === "waiting" && typeof rec.progress_label === "string" && rec.progress_label.includes("permission response") && typeof rec.lane_id === "string")
1491
1641
  awaitingPermissionLaneIds.delete(rec.lane_id);
1492
1642
  }
1643
+ let uiCacheRefreshed = false;
1493
1644
  for (const record of childRecords) {
1494
1645
  const laneId = typeof record.lane_id === "string" ? record.lane_id : "";
1495
1646
  const childSessionId = typeof record.child_session_id === "string" ? record.child_session_id : "";
1496
1647
  if (!laneId || !childSessionId)
1497
1648
  continue;
1498
1649
  if (terminalLaneIds.has(laneId)) {
1499
- if (terminalTaskResultLaneIds.has(laneId)) {
1650
+ // Refresh the completion UI cache for terminal lanes so stale "running"
1651
+ // rows are promoted to terminal. This must run for any terminal lane,
1652
+ // including lanes that only have lane_lifecycle/task_failed evidence and
1653
+ // no task_result (e.g. reviewer execution bridge writing only
1654
+ // lane_lifecycle=invocation_failed). Without this, the sidebar row stays
1655
+ // stuck at progressing_normal/running until a task_result appears.
1656
+ if (!uiCacheRefreshed) {
1500
1657
  refreshFlowDeskCompletionUiCachesV1({
1501
1658
  rootDir: input.rootDir,
1502
1659
  workflowId: input.workflowId,
1503
- observedAt: new Date(nowMs).toISOString(),
1660
+ observedAt: terminalRefreshObservedAt,
1504
1661
  });
1662
+ uiCacheRefreshed = true;
1505
1663
  }
1506
1664
  continue; // already done
1507
1665
  }
@@ -1544,6 +1702,8 @@ export async function monitorChildSessionsV1(input) {
1544
1702
  output_kind: resultObservation.outputKind,
1545
1703
  usable_for_synthesis: resultObservation.usableForSynthesis,
1546
1704
  missing_contract: false,
1705
+ finalization_reason: "terminal_marker",
1706
+ looks_like_refusal_or_error: resultObservation.looksLikeRefusalOrError,
1547
1707
  created_at: completedAt,
1548
1708
  dispatch_authority_enabled: false,
1549
1709
  });
@@ -1572,8 +1732,43 @@ export async function monitorChildSessionsV1(input) {
1572
1732
  progressLabel: "async agent task result persistence failed",
1573
1733
  observedAt: completedAt,
1574
1734
  });
1735
+ refreshFlowDeskCompletionUiCachesV1({
1736
+ rootDir: input.rootDir,
1737
+ workflowId: input.workflowId,
1738
+ observedAt: completedAt,
1739
+ });
1575
1740
  continue;
1576
1741
  }
1742
+ const observedReviewerVerdict = observedTopTierReviewerVerdictFromText({
1743
+ text: resultObservation.text,
1744
+ workflowId: input.workflowId,
1745
+ });
1746
+ const reviewerVerdictPersisted = observedReviewerVerdict === undefined
1747
+ ? false
1748
+ : persistObservedReviewerVerdict({
1749
+ rootDir: input.rootDir,
1750
+ workflowId: input.workflowId,
1751
+ verdict: observedReviewerVerdict,
1752
+ });
1753
+ const runningLifecycle = reloaded.entries.find((entry) => {
1754
+ const lifecycle = entry.record;
1755
+ return entry.evidenceClass === "lane_lifecycle" && lifecycle.lane_id === laneId && typeof lifecycle.attempt_id === "string";
1756
+ })?.record;
1757
+ if (reviewerVerdictPersisted && observedReviewerVerdict !== undefined) {
1758
+ writeAgentTaskCompleteLifecycleForVerdict({
1759
+ rootDir: input.rootDir,
1760
+ workflowId: input.workflowId,
1761
+ laneId,
1762
+ attemptId: typeof runningLifecycle?.attempt_id === "string" ? runningLifecycle.attempt_id : `attempt-${laneId}`,
1763
+ parentSessionRef: typeof record.parent_session_ref === "string" ? record.parent_session_ref : "ses-agent-task-parent",
1764
+ childSessionId,
1765
+ taskResultEvidenceId,
1766
+ agentRef,
1767
+ providerQualifiedModelId: modelId,
1768
+ verdictId: observedReviewerVerdict.verdict_id,
1769
+ observedAt: completedAt,
1770
+ });
1771
+ }
1577
1772
  writeAgentTaskProgressEvidence({
1578
1773
  rootDir: input.rootDir,
1579
1774
  workflowId: input.workflowId,
@@ -1583,7 +1778,9 @@ export async function monitorChildSessionsV1(input) {
1583
1778
  providerQualifiedModelId: modelId,
1584
1779
  phase: "finalizing",
1585
1780
  progressSeq: 10 + nudgeCount,
1586
- progressLabel: "async agent task result captured by watchdog",
1781
+ progressLabel: reviewerVerdictPersisted
1782
+ ? "async agent task result captured with reviewer verdict evidence"
1783
+ : "async agent task result captured by watchdog",
1587
1784
  observedAt: completedAt,
1588
1785
  });
1589
1786
  refreshFlowDeskCompletionUiCachesV1({
@@ -1622,7 +1819,11 @@ export async function monitorChildSessionsV1(input) {
1622
1819
  completion_status: "partial",
1623
1820
  output_kind: partialObservation.outputKind,
1624
1821
  usable_for_synthesis: partialObservation.usableForSynthesis,
1625
- missing_contract: true,
1822
+ // Captured partial text is still a usable result, not a contract
1823
+ // failure. The coordinator judges substance from the advisory fields.
1824
+ missing_contract: false,
1825
+ finalization_reason: "timeout_partial",
1826
+ looks_like_refusal_or_error: partialObservation.looksLikeRefusalOrError,
1626
1827
  created_at: abortedAt,
1627
1828
  dispatch_authority_enabled: false,
1628
1829
  });
@@ -1675,6 +1876,11 @@ export async function monitorChildSessionsV1(input) {
1675
1876
  progressLabel: "async agent task aborted after no response",
1676
1877
  observedAt: abortedAt,
1677
1878
  });
1879
+ refreshFlowDeskCompletionUiCachesV1({
1880
+ rootDir: input.rootDir,
1881
+ workflowId: input.workflowId,
1882
+ observedAt: abortedAt,
1883
+ });
1678
1884
  result.lanesAborted++;
1679
1885
  continue;
1680
1886
  }
@@ -1709,6 +1915,20 @@ export async function monitorChildSessionsV1(input) {
1709
1915
  });
1710
1916
  }
1711
1917
  }
1918
+ // Invariant: terminal/failure lanes observed during this cycle MUST cause a
1919
+ // completion UI cache refresh, even when the failed lane has no paired
1920
+ // `agent_task_child_session` record (e.g. reviewer execution bridge wrote
1921
+ // only `lane_lifecycle=invocation_failed`, or `task_failed`/`no_output`
1922
+ // arrived via the event hook without a task_result). Without this defensive
1923
+ // refresh, the `subtask-activity-sidebar` and `auto-next-ready` caches stay
1924
+ // stuck at `progressing_normal/running` until the next backfill pass.
1925
+ if (!uiCacheRefreshed && terminalLaneIds.size > 0) {
1926
+ refreshFlowDeskCompletionUiCachesV1({
1927
+ rootDir: input.rootDir,
1928
+ workflowId: input.workflowId,
1929
+ observedAt: terminalRefreshObservedAt,
1930
+ });
1931
+ }
1712
1932
  return result;
1713
1933
  }
1714
1934
  //# sourceMappingURL=stall-recovery.js.map