diff --git a/packages/ui/src/features/canvas/components/ActivityTimeline.test.tsx b/packages/ui/src/features/canvas/components/ActivityTimeline.test.tsx
index b6ea0cb52d..8d0e777678 100644
--- a/packages/ui/src/features/canvas/components/ActivityTimeline.test.tsx
+++ b/packages/ui/src/features/canvas/components/ActivityTimeline.test.tsx
@@ -128,4 +128,37 @@ describe("ActivityTimeline", () => {
expect(screen.getByText("Saved workspace context")).toBeVisible();
expect(useThreadNavigationStore.getState().scrollRequests).toEqual({});
});
+
+ it("hides injected custom instructions from conversation previews", () => {
+ renderTimeline(true, [
+ {
+ type: "user_message",
+ id: "custom-instructions-message",
+ content:
+ "Review this PR\n\n\nThe user has saved custom instructions that apply to all of their tasks. Follow them.\n\nNever update an existing PR description.\n",
+ timestamp: Date.parse("2026-07-17T09:05:00Z"),
+ },
+ ]);
+
+ expect(screen.getByText("Review this PR")).toBeInTheDocument();
+ expect(screen.queryByText(/user_custom_instructions/)).toBeNull();
+ expect(
+ screen.queryByText("Never update an existing PR description."),
+ ).toBeNull();
+ });
+
+ it("shows user-authored custom-instruction tag examples", () => {
+ renderTimeline(true, [
+ {
+ type: "user_message",
+ id: "literal-custom-instructions-message",
+ content:
+ "Render this example: be terse",
+ timestamp: Date.parse("2026-07-17T09:05:00Z"),
+ },
+ ]);
+
+ expect(screen.getByText(/user_custom_instructions/)).toBeInTheDocument();
+ expect(screen.getByText(/be terse/)).toBeInTheDocument();
+ });
});
diff --git a/packages/ui/src/features/canvas/components/ActivityTimeline.tsx b/packages/ui/src/features/canvas/components/ActivityTimeline.tsx
index 94915cc36b..c899b0bbd2 100644
--- a/packages/ui/src/features/canvas/components/ActivityTimeline.tsx
+++ b/packages/ui/src/features/canvas/components/ActivityTimeline.tsx
@@ -34,6 +34,7 @@ import { ThreadTimestamp } from "@posthog/ui/features/canvas/components/ThreadTi
import { userDisplayName } from "@posthog/ui/features/canvas/utils/userDisplay";
import type { buildConversationItems } from "@posthog/ui/features/sessions/components/buildConversationItems";
import { extractChannelContext } from "@posthog/ui/features/sessions/components/session-update/channelContext";
+import { extractCustomInstructions } from "@posthog/ui/features/sessions/components/session-update/customInstructions";
import { useThreadNavigationStore } from "@posthog/ui/features/sessions/threadNavigationStore";
import { Fragment, type KeyboardEvent, type ReactNode, useMemo } from "react";
@@ -83,7 +84,12 @@ function UserMessageRow({
() => extractChannelContext(content),
[content],
);
- const displayContent = channelContext?.stripped ?? content;
+ const afterChannelContext = channelContext?.stripped ?? content;
+ const customInstructions = useMemo(
+ () => extractCustomInstructions(afterChannelContext),
+ [afterChannelContext],
+ );
+ const displayContent = customInstructions?.stripped ?? afterChannelContext;
// The row itself is the hit target. `ThreadItem` renders an , which a
//