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.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 import org.junit.jupiter.api.assertDoesNotThrow class NoExecutionCouplingTest { @Test fun `engine does not mutate grants or context`() { val engine = DefaultApprovalEngine() val grants = mutableListOf( ApprovalGrant( GrantId("g1"), GrantScope.SESSION(), setOf(Tier.T2), "", Instant.parse("2026-01-01T00:00:00Z") ) ) val originalGrants = grants.toList() val ctx = ApprovalContext( ApprovalScopeIdentity(SessionId("s1"), null, null), ApprovalMode.DENY ) val now = Instant.parse("2026-01-01T00:00:01Z") engine.evaluate(request("r1", Tier.T2), ctx, grants, now) assertEquals(originalGrants, grants, "Grants list must not be mutated") assertEquals(ApprovalMode.DENY, ctx.mode, "Context must not be mutated") } @Test fun `engine does not throw for valid input`() { val engine = DefaultApprovalEngine() assertDoesNotThrow { engine.evaluate( request("r1", Tier.T0), ApprovalContext( ApprovalScopeIdentity(SessionId("s1"), null, null), ApprovalMode.YOLO ), emptyList(), Instant.parse("2026-01-01T00:00:01Z") ) } } }