diff --git a/packages/react/src/Timeline/Timeline.code-scanning.features.stories.tsx b/packages/react/src/Timeline/Timeline.code-scanning.features.stories.tsx
index 9e03994be10..1edbc345fb2 100644
--- a/packages/react/src/Timeline/Timeline.code-scanning.features.stories.tsx
+++ b/packages/react/src/Timeline/Timeline.code-scanning.features.stories.tsx
@@ -26,6 +26,7 @@ import {
UserActor,
VariantSection,
} from './internal/timelineStoryHelpers'
+import {CODE_SCANNING_TAXONOMY, actorTypeForLogin, toEventDataAttributes, type CodeScanningEventType} from './taxonomy'
import classes from './Timeline.code-scanning.features.stories.module.css'
/**
@@ -172,6 +173,26 @@ const ConfigPill = ({category}: {category: string}) => (
*/
const SubRow = ({children}: {children: React.ReactNode}) =>
{children}
+/**
+ * Per-row taxonomy `data-*` attributes (Phase 3 tagging, github/primer#6664,
+ * epic #6654). Projects a Code Scanning leaf event type through the shared
+ * `toEventDataAttributes` serializer from the taxonomy module (primer/react#8180),
+ * mirroring the License Compliance pilot (primer/react#8216). `category` and
+ * `visibility` are derived FROM `CODE_SCANNING_TAXONOMY` so the story never
+ * hand-maintains them. Pass the row's rendered `UserActor` login for USER events
+ * (resolves `data-actor-type` via `actorTypeForLogin`); omit it for SYSTEM rows
+ * so `data-actor-type` is left off entirely. Spread the result onto each
+ * `Timeline.Item`.
+ */
+const codeScanningAttrs = (type: CodeScanningEventType, login?: string) =>
+ toEventDataAttributes({
+ scope: 'code-scanning',
+ type,
+ category: CODE_SCANNING_TAXONOMY[type].category,
+ visibility: CODE_SCANNING_TAXONOMY[type].visibility,
+ actorType: login ? actorTypeForLogin(login) : undefined,
+ })
+
export default {
title: 'Components/Timeline/Events/Code Scanning',
component: Timeline,
@@ -219,7 +240,7 @@ export const EventDetected = () => (
sub-row, and a right-aligned tool-version Label (Timeline.Actions). */}
-
+
@@ -253,7 +274,7 @@ export const EventDetected = () => (
card — `show_timeline_commit?` is false for this event). */}
-
+
@@ -283,7 +304,7 @@ export const EventDetected = () => (
{category}" pill (rendered when the alert has more than one category). */}
-
+
@@ -314,13 +335,20 @@ export const EventDetected = () => (
* Config-deleted renders the analysis category as an inline subtle mono pill
* (`MonoPill`); when the category is empty the live ERB substitutes "API
* Upload".
+ *
+ * TAXONOMY (github/primer#6664): the two "Fixed in branch" rows are the
+ * ALERT_CLOSED_BECAME_FIXED wire event and carry `data-event-type="fixed"`. The
+ * two "Configuration deleted" rows are visually grouped under Fixed here, but the
+ * taxonomy catalog folds their ALERT_CLOSED_BECAME_OUTDATED wire event into
+ * `closed` (a SYSTEM closure), so those rows carry `data-event-type="closed"`.
+ * Both are system events with no actor, so neither emits `data-actor-type`.
*/
export const EventFixed = () => (
{/* Fixed — selected ref → SOLID purple shield-check */}
-
+
@@ -335,7 +363,7 @@ export const EventFixed = () => (
{/* Fixed — non-selected ref → bare default check */}
-
+
@@ -348,9 +376,12 @@ export const EventFixed = () => (
{/* Config deleted — selected ref → SOLID purple shield-check */}
+ {/* Config-deletion is the ALERT_CLOSED_BECAME_OUTDATED wire event, which the
+ taxonomy folds into `closed` (system closure), not `fixed` — so this row
+ carries data-event-type="closed" despite its visual "Fixed" grouping. */}
-
+
@@ -366,7 +397,7 @@ export const EventFixed = () => (
{/* Config deleted — non-selected ref → bare default check */}
-
+
@@ -398,7 +429,7 @@ export const EventClosedByUser = () => (
{/* Closed as false positive — with a resolution-note sub-row */}
-
+
@@ -415,7 +446,7 @@ export const EventClosedByUser = () => (
{/* Closed as used in tests */}
-
+
@@ -431,7 +462,7 @@ export const EventClosedByUser = () => (
{/* Closed as won't fix */}
-
+
@@ -448,7 +479,7 @@ export const EventClosedByUser = () => (
`resolution == :NO_RESOLUTION`. */}
-
+
@@ -475,7 +506,7 @@ export const EventReopened = () => (
-
+
@@ -510,7 +541,7 @@ export const EventDismissalRequested = () => (
-
+
@@ -550,7 +581,7 @@ export const EventDismissalReviewed = () => (
{/* Approved — check icon + reviewer-comment sub-row */}
-
+
@@ -567,7 +598,7 @@ export const EventDismissalReviewed = () => (
{/* Denied — x icon */}
-
+