import com.correx.core.approvals.GrantScope import com.correx.core.approvals.Tier import com.correx.core.approvals.domain.DefaultApprovalEngine import com.correx.core.approvals.model.ApprovalContext import com.correx.core.approvals.model.ApprovalGrant import com.correx.core.approvals.model.ApprovalScopeIdentity import com.correx.core.events.types.ApprovalDecisionId import com.correx.core.events.types.GrantId import com.correx.core.events.types.SessionId import com.correx.core.sessions.ApprovalMode import com.correx.testing.fixtures.request import kotlinx.datetime.Instant import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test class ApprovalReplayTest { @Test fun `replaying same request with same inputs yields identical decision`() { val engine1 = DefaultApprovalEngine() val engine2 = DefaultApprovalEngine() val req = request("req1", Tier.T2) val ctx = ApprovalContext( ApprovalScopeIdentity(SessionId("s1"), null, null), ApprovalMode.AUTO ) val grants = listOf( ApprovalGrant( GrantId("g1"), GrantScope.SESSION(), setOf(Tier.T2), "reason", Instant.parse("2026-01-01T00:00:00Z") ) ) val now = Instant.parse("2026-01-01T00:00:01Z") val d1 = engine1.evaluate(req, ctx, grants, now) val d2 = engine2.evaluate(req, ctx, grants, now) assertEquals(d1, d2) } @Test fun `decision ID determinism holds over multiple replays`() { val engine = DefaultApprovalEngine() val req = request("fixed", Tier.T3) val ctx = ApprovalContext( ApprovalScopeIdentity(SessionId("s"), null, null), ApprovalMode.PROMPT ) val now = Instant.parse("2026-01-01T00:00:01Z") val d1 = engine.evaluate(req, ctx, emptyList(), now) val d2 = engine.evaluate(req, ctx, emptyList(), now) assertEquals(d1.id, d2.id) assertEquals(ApprovalDecisionId("decision:fixed"), d1.id) } }