FN-6030: fix workflow terminal notifications

Ensure merged workflow tasks still emit the expected terminal notifications.

- emit task:merged when PR-driven workflow merges move tasks to done
- send merged notifications for merge-backed done transitions and suppress duplicates
- add regression coverage, a published changeset, and reconcile overlapping docs/test updates

Files changed:
 .../fn-6030-workflow-terminal-notifications.md     |   5 +
 docs/storage.md                                    |   8 +-
 .../core/src/__tests__/builtin-workflows.test.ts   |   1 -
 .../__tests__/store-pr-merged-transition.test.ts   |  14 ++-
 .../src/__tests__/workflow-ir-resolver.test.ts     |   1 -
 packages/core/src/store.ts                         |  14 ++-
 .../settings/sections/ProjectModelsSection.tsx     |   3 +-
 .../engine/src/__tests__/merger-post-merge.test.ts |   9 +-
 .../src/__tests__/notification-service.test.ts     | 129 ++++++++++++++++++++-
 .../__tests__/workflow-graph-task-runner.test.ts   |  57 +++++++++
 .../src/notification/notification-service.ts       |  36 ++++--
 11 files changed, 257 insertions(+), 20 deletions(-)

Fusion-Task-Id: FN-6030

Fusion-Task-Lineage: a991f765-0986-4541-ab38-ff476cf88d16
This commit is contained in:
gsxdsm
2026-06-08 13:54:17 -07:00
parent ed0dc4a7b9
commit 4ffd0a2dde
11 changed files with 257 additions and 20 deletions

View File

@@ -11809,13 +11809,25 @@ ${TASK_UPSERT_SQL_ASSIGNMENTS}
return { moved: false, skipped: "wrong-column" };
}
await this.moveTask(taskId, "done", {
const movedTask = await this.moveTask(taskId, "done", {
moveSource: "engine",
preserveProgress: true,
preserveWorktree: true,
skipMergeBlocker: true,
});
this.emit("task:merged", {
task: movedTask,
branch: movedTask.branch ?? movedTask.prInfo?.headBranch ?? freshTask.branch ?? freshTask.prInfo?.headBranch ?? "",
merged: true,
worktreeRemoved: false,
branchDeleted: false,
mergeConfirmed: movedTask.mergeDetails?.mergeConfirmed ?? freshTask.mergeDetails?.mergeConfirmed,
mergedAt: movedTask.mergeDetails?.mergedAt ?? freshTask.mergeDetails?.mergedAt,
mergeTargetBranch: movedTask.mergeDetails?.mergeTargetBranch ?? freshTask.mergeDetails?.mergeTargetBranch,
mergeTargetSource: movedTask.mergeDetails?.mergeTargetSource ?? freshTask.mergeDetails?.mergeTargetSource,
} satisfies MergeResult);
if (ctx?.agentId && ctx?.runId) {
this.recordRunAuditEvent({
taskId,