= test-replay

== purpose

Tests that verify the event replay mechanism produces identical state regardless of when or how events are replayed. Ensures that projections are deterministic and that the full event stream can be reconstructed faithfully.

== responsibilities

* Verify that session state rebuilt from replay matches expected outcomes
* Test replay produces correct results for empty event streams (no events)
* Validate that transition-driven workflows replay to the correct final state
* Verify that approval decisions survive replay and produce correct state
* Test that validation pipeline events are correctly replayed and ordered

== non-responsibilities

* Does not test live streaming or real-time event processing
* Does not test performance characteristics of replay (only correctness)
* Does not test cross-session replay interactions

== key types

=== SessionReplayTest
* **kind**: JUnit 5 test class
* **purpose**: Verifies that full event streams replayed from the beginning produce the expected session state.

=== SessionEmptyReplayTest
* **kind**: JUnit 5 test class
* **purpose**: Verifies replay behavior when no events have been recorded — the empty state case.

=== TransitionReplayIntegrationTest
* **kind**: JUnit 5 test class
* **purpose**: Tests that a multi-stage workflow with transitions replays to the correct final orchestration state.

=== ApprovalReplayTest
* **kind**: JUnit 5 test class
* **purpose**: Verifies that approval request and decision events are correctly replayed and produce the expected approval state.

=== ValidationReplayTest
* **kind**: JUnit 5 test class
* **purpose**: Tests replay of validation events through the validation pipeline.

== event flow

*inbound:* Constructed `NewEvent` instances simulating domain events (session start, stage transitions, approvals, tool invocations).

*outbound:* Assertions against rebuilt `SessionState`, `OrchestrationState`, `ApprovalState`.

== integration points

* `:core:sessions` — `DefaultSessionReducer`, `SessionProjector`, `SessionState`
* `:core:kernel` — `OrchestrationState`, `DefaultOrchestrationReducer`
* `:core:approvals` — `ApprovalState`, `DefaultApprovalReducer`, `ApprovalProjector`
* `:core:validation` — `ValidationPipeline`
* `:core:events` — `EventStore`, `StoredEvent`, event payload types
* `:testing:fixtures` — `EventFixtures`, `ApprovalFixtures`, `WorkflowFixtures`

== invariants

* Replay from an empty event store produces initial (empty/default) state
* Replay from a full event log produces the same state as when the events were first applied
* Approval decisions are persisted as events and survive replay

== PlantUML diagram

[plantuml, test-replay, "png"]
----
include::../../diagrams/test-replay.puml[]
----




== known issues

* Tests may rely on `InMemoryEventStore` which may not perfectly reproduce the behavior of the production SQLite-backed store

== open questions

* Should replay tests verify that replay is idempotent (replaying the same stream twice produces identical state)?
