diff --git a/src/Agent/AutopilotMonitor.Agent.V2.Core.Tests/Telemetry/Events/EventTimelineEmitterDecisionStateEnrichmentTests.cs b/src/Agent/AutopilotMonitor.Agent.V2.Core.Tests/Telemetry/Events/EventTimelineEmitterDecisionStateEnrichmentTests.cs
new file mode 100644
index 00000000..29253a4b
--- /dev/null
+++ b/src/Agent/AutopilotMonitor.Agent.V2.Core.Tests/Telemetry/Events/EventTimelineEmitterDecisionStateEnrichmentTests.cs
@@ -0,0 +1,238 @@
+using System;
+using System.Collections.Generic;
+using AutopilotMonitor.Agent.V2.Core.Telemetry.Events;
+using AutopilotMonitor.Agent.V2.Core.Tests.Harness;
+using AutopilotMonitor.DecisionCore.Engine;
+using AutopilotMonitor.DecisionCore.State;
+using AutopilotMonitor.Shared.Models;
+using Newtonsoft.Json.Linq;
+using SharedConstants = AutopilotMonitor.Shared.Constants;
+using Xunit;
+
+namespace AutopilotMonitor.Agent.V2.Core.Tests.Telemetry.Events
+{
+ ///
+ /// Tests for the decisionState-snapshot enrichment in
+ /// (Plan §A — Edge-Triggered State
+ /// Snapshots, 2026-05-03). The enrichment runs after ResolveData so it
+ /// works for both event paths (parameter-rebuilt Data and typedPayload-merged
+ /// Data) and never clobbers existing event-specific fields.
+ ///
+ public sealed class EventTimelineEmitterDecisionStateEnrichmentTests
+ {
+ private static readonly DateTime At = new DateTime(2026, 5, 1, 13, 45, 32, DateTimeKind.Utc);
+
+ private sealed class Rig : IDisposable
+ {
+ public TempDirectory Tmp { get; } = new TempDirectory();
+ public FakeTelemetryTransport Transport { get; } = new FakeTelemetryTransport();
+ public EventSequenceCounter Counter { get; }
+ public TelemetryEventEmitter Inner { get; }
+ public EventTimelineEmitter Sut { get; }
+
+ public Rig()
+ {
+ Counter = new EventSequenceCounter(new EventSequencePersistence(Tmp.File("seq.json")));
+ Inner = new TelemetryEventEmitter(Transport, Counter, "S1", "T1");
+ Sut = new EventTimelineEmitter(Inner);
+ }
+
+ public JObject EmittedData() =>
+ (JObject)JObject.Parse(Transport.Enqueued[0].PayloadJson)["Data"]!;
+
+ public void Dispose() => Tmp.Dispose();
+ }
+
+ private static DecisionState State() => DecisionState.CreateInitial("S1", "T1");
+
+ // ============================================================================
+ // Full-coverage: every anchor event-type gets decisionState enrichment
+ // ============================================================================
+
+ public static IEnumerable