Files
fusion/packages/core/src/builtin-completion-summary-node.ts
gsxdsm 38841695c8 fix: stop triage loop at completion-summary node and i18n object-key crashes (#1863)
Two distinct v0.52.0 regressions reported in issue #1863.

1. Triage loop (engine): the best-effort completion-summary graph node is
   wired into every built-in workflow with a success-only edge. A thrown
   handler exception or a failed summary projection write bypassed the
   advisory `!blocking -> success` coercion, terminated the graph at
   'completion-summary', and routeGraphFailureToExecutionResume bounced the
   in-review task back to todo forever (token usage 0, execution NOT STARTED).
   The graph executor now degrades a completion-summary node failure to
   success (ensureWorkflowCompletionSummary still backfills task.summary), with
   a routeGraphFailureToExecutionResume backstop. Shared isCompletionSummaryNode
   predicate exported from @fusion/core.

2. i18n object-key crashes (dashboard): three views called t() with keys that
   resolve to nested objects (taskDetail.executionMode, routing.source,
   nodes.dockerHost), so i18next returned "returned an object instead of
   string" and crashed the render. Added leaf label keys across all locales and
   switched the callers.

Tests: engine non-fatal completion-summary regression (fails without the fix),
dashboard invariant guard scanning t("literal") callers against real en/app.json,
and a Stats-panel reproduction against the real bundle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 16:43:08 -07:00

50 lines
2.2 KiB
TypeScript

import type { WorkflowIrNode } from "./workflow-ir-types.js";
export const COMPLETION_SUMMARY_NODE_ID = "completion-summary";
/*
* FNXC:WorkflowCompletion 2026-07-01-16:20:
* Single source of truth for "is this the advisory completion-summary projection
* node?". The engine, graph executor, and lifecycle validation all key summary
* behavior off `summaryTarget: "task"` (built-in id `completion-summary`). This
* node is BEST-EFFORT: `ensureWorkflowCompletionSummary` deterministically
* backfills `task.summary` at the review/done boundary, and every built-in
* workflow wires it with a success-only edge (no failure edge — see
* `builtin-workflows.ts` `linear()` and the `*-workflow-ir.ts` graphs). So a
* summary-node failure must never terminate or loop the graph (issue #1863).
*/
export function isCompletionSummaryNode(node: { id?: string; config?: Record<string, unknown> }): boolean {
return node.config?.summaryTarget === "task" || node.id === COMPLETION_SUMMARY_NODE_ID;
}
const COMPLETION_SUMMARY_PROMPT = `Generate the final completion summary for this task.
Use the task description, executed workflow context, changed files/diff, verification notes, and any produced artifacts.
Output 2-4 concise sentences for the task card and downstream integrations:
- state what was completed,
- mention important files/artifacts or user-visible behavior when known,
- mention verification performed or why verification was not applicable,
- do not include markdown headings, bullet lists, verdict JSON, or process narration.`;
export function completionSummaryNode(column: string): WorkflowIrNode {
return {
id: COMPLETION_SUMMARY_NODE_ID,
kind: "prompt",
column,
config: {
/*
* FNXC:WorkflowCompletion 2026-06-29-11:09:
* Built-in workflows must generate a real agent-authored completion summary
* as part of graph execution, not rely only on a recovery fallback after the
* task reaches review/done. The engine treats `summaryTarget: "task"` as a
* projection contract and persists this node's output to `task.summary`.
*/
name: "Completion summary",
prompt: COMPLETION_SUMMARY_PROMPT,
toolMode: "readonly",
summaryTarget: "task",
},
};
}