diff --git a/.changeset/fn-7924-artifact-mail-view-task-link.md b/.changeset/fn-7924-artifact-mail-view-task-link.md
new file mode 100644
index 0000000000..9889d22de6
--- /dev/null
+++ b/.changeset/fn-7924-artifact-mail-view-task-link.md
@@ -0,0 +1,7 @@
+---
+"@runfusion/fusion": minor
+---
+
+summary: Artifact-registration mail notifications now include a "View task" link to open the producing task.
+category: feature
+dev: MailboxArtifactAttachment renders a metadata-driven View-task affordance (message.metadata.taskId + onOpenTask); MainContent wires MailboxView's onOpenTask via fetchTaskDetail -> openDetailTask.
diff --git a/docs/dashboard-guide.md b/docs/dashboard-guide.md
index d3234ade64..c8973d378c 100644
--- a/docs/dashboard-guide.md
+++ b/docs/dashboard-guide.md
@@ -627,7 +627,7 @@ Mailbox view shows inbox/outbox communication threads and unread state.
- Inbox renders one row per message (no sender-based collapsing)
- clicking a message in the Mail tab opens the task detail pane with full message content and conversation context
- reply rows in the mailbox modal can expand inline to show the replied-to message context for easier thread reading
-- when an agent or dashboard chat session registers an artifact with `fn_artifact_register`, Fusion sends a best-effort `system` → user inbox message announcing the new artifact (for example, `New image artifact registered:
`) with metadata for `artifactId`, `artifactType`, `title`, optional `mimeType`, `authorId`, and optional `taskId`; notification delivery is informational and never blocks or rolls back the artifact registration. Artifact notifications are actionable in message detail views: image artifacts show an inline preview plus **Open artifact**, while video/audio/document/other artifacts show an **Open artifact** link to the managed media URL.
+- when an agent or dashboard chat session registers an artifact with `fn_artifact_register`, Fusion sends a best-effort `system` → user inbox message announcing the new artifact (for example, `New image artifact registered: `) with metadata for `artifactId`, `artifactType`, `title`, optional `mimeType`, `authorId`, and optional `taskId`; notification delivery is informational and never blocks or rolls back the artifact registration. Artifact notifications are actionable in message detail views: image artifacts show an inline preview plus **Open artifact**, while video/audio/document/other artifacts show an **Open artifact** link to the managed media URL. When `taskId` metadata is present, the same artifact block also shows **View task** so users can open the producing task detail directly from the mailbox.
- on first engine startup under Fusion `0.59.x`, each project receives one best-effort `system` inbox notice about the upcoming embedded-Postgres storage migration with the Discord help link; `metadata.kind = "postgres-migration-notice"` prevents duplicates across restarts.
- mailbox now includes an **Approvals** tab with pending and history filters (`approved` / `denied` / `completed`), approval detail context, and inline approve/deny actions for pending requests
- for approvals gated by an agent's permission policy (permanent agents and task-worker heartbeats), the Approvals detail pane renders the gated action's real payload — tool name, shell command line or structured arguments, and working directory when present — instead of only a generic "Agent gated action for ``" summary; a stateless heartbeat retrying the same gated command reuses the existing pending approval instead of creating a duplicate (FN-7609)
diff --git a/packages/dashboard/app/components/MailboxArtifactAttachment.tsx b/packages/dashboard/app/components/MailboxArtifactAttachment.tsx
index 4cd6e6443b..0844158017 100644
--- a/packages/dashboard/app/components/MailboxArtifactAttachment.tsx
+++ b/packages/dashboard/app/components/MailboxArtifactAttachment.tsx
@@ -8,6 +8,8 @@ export interface MailboxArtifactAttachmentProps {
title?: unknown;
mimeType?: unknown;
projectId?: string;
+ taskId?: unknown;
+ onOpenTask?: (taskId: string) => void;
}
function readString(value: unknown): string | undefined {
@@ -23,6 +25,9 @@ function readArtifactType(value: unknown): ArtifactType | "unknown" {
/**
* FNXC:ArtifactRegistry 2026-07-12-00:00:
* Artifact-registration mail messages must expose the artifact announced by message.metadata. Render image artifacts inline, keep every type reachable through artifactMediaUrl(projectId-aware), and render nothing when metadata has no artifactId so ordinary messages keep their exact layout.
+ *
+ * FNXC:ArtifactRegistry 2026-07-12-00:00:
+ * Artifact-registration mail messages must also expose the producing task when message.metadata.taskId is paired with an onOpenTask handler. Render no task affordance when either side is absent so artifact-only and ordinary messages do not gain empty shells.
*/
export const MailboxArtifactAttachment = memo(function MailboxArtifactAttachment({
artifactId,
@@ -30,11 +35,14 @@ export const MailboxArtifactAttachment = memo(function MailboxArtifactAttachment
title,
mimeType,
projectId,
+ taskId,
+ onOpenTask,
}: MailboxArtifactAttachmentProps) {
const id = readString(artifactId);
const type = readArtifactType(artifactType);
const label = readString(title) ?? "artifact";
const mediaMimeType = readString(mimeType);
+ const task = readString(taskId);
const [imageFailed, setImageFailed] = useState(false);
const mediaUrl = useMemo(() => id ? artifactMediaUrl(id, projectId) : "", [id, projectId]);
@@ -51,6 +59,17 @@ export const MailboxArtifactAttachment = memo(function MailboxArtifactAttachment
Open artifact
);
+ const taskLink = task && onOpenTask ? (
+
+ ) : null;
let preview: ReactNode = null;
if (type === "image" && !imageFailed) {
@@ -97,6 +116,7 @@ export const MailboxArtifactAttachment = memo(function MailboxArtifactAttachment
{preview}