So, if you disregard all the "aggregate design rules" talk you can find on the net, and focus on how aggregates are described in the book, they are meant to be these bundles of objects that form some sort of a graph, with an explicit design boundary, and one object selected as the root. The root acts as an interface (facade) to the aggregate, it encapsulates it, and is responsible for maintaining consistency within that boundary. Your domain model is then, more or less, composed of a number such aggregates that can be reached by traversal. Another important role the aggregates have is to simplify the web of dependencies between objects, so aggregate relationships should be strategically designed.
The question is, how do you obtain the initial aggregates - the ones you start the traversal from?
If you take a closer look at how Evans defined repositories, the emphasis is not on persistence (although generally speaking they do eventually end up going to the database) - instead they are a means to obtain the initial "surface level" aggregate roots, letting you start there and reach the others via traversal.
To quote the Blue Book:
"Whether to provide a traversal or depend on a [database] search
becomes a design decision, trading off the decoupling of the search
against the cohesiveness of the association. [...] The right
combination of search and association makes the design
That means that the dependency structure is such that (1) when an execution path is entered, a Use Case1 that needs an aggregate must ask a repository to obtain one, and (2) the the repository knows about certain "surface level" aggregates, but the core domain doesn't know about repositories.
There is some room for variation when it comes to how you organize that into layers, but you can see that the above structure imposes some constraints on the dependency directions across and within layers. So to answer you question.
- Which layer Repositories belong: the Domain Layer, Persistence Layer or something in the middle?
A repository as conceptualized by DDD is an abstraction - it is not itself in the persistence layer, it encapsulates database access - meaning that it forwards reconstitution request to some data access gateway that is in the persistence layer (either via composition, or via dynamic dispatch).
"For each type of object that needs global access [...] set up access through a well-known global interface. [Repositories encapsulate] the actual storage and query technology. Provide REPOSITORIES only for AGGREGATE roots that actually need direct access."
They are meant to be accessible throughout the application layer, so that seems to be a natural place for them to reside, but the actual implementation will go across layers. The reason for the encapsulation is to keep application service layer code simple and decoupled from persistence-related boilerplate.
(It seems that if it were below Domain Layer it would violate Layered Architecture principle, because it depends on a domain object which it stores)
The repository abstraction is not below the Domain Layer, but it does depend on the domain objects - that's the whole point. You ask it for an aggregate root using the language of the domain model (e.g., you pass it an ID), it then figures out how to turn that into a database query; the database returns its representation, and the repository then uses it to reconstitute the requested aggregate, and returns that. Beyond that, it doesn't contain any significant business logic, and it certainly doesn't contain any problem-specific (core) domain logic.
In practice, though, you want to try and arrange things in a way that avoids elaborate and costly translations between representations.
Another thing that is discussed in the book is that it is desirable to find a way to express aggregate boundaries in the code itself, but that it can be a bit tricky to do so. The most common thing you'll find on the web is the idea popularized by Vaughn Vernon, that states that aggregates should reference other aggregates exclusively via their identity. This can work well in many cases, and has the advantage of clearly delineating aggregate boundaries in code, but IMO it's too restrictive and somewhat database-centric in thinking for it to be elevated to the status of a rule that you enforce or even default to when it comes to aggregate design. So don't think of it as the only option - you could design a different scheme.
If you do go down that path, then you have to figure out how to traverse across aggregates given that specific restriction. Vaughn Vernon recommends to "use a repository or domain service to look up dependent objects ahead of invoking the aggregate behavior" (and not use a repository from within the aggregate, to prevent the aggregates from having a dependency on one or more repositories).
There's a bit of a tradeoff here (as with every design decision): A certain amount of knowledge about the inner workings of the aggregate is being pushed elsewhere, and the signatures of the aggregates' methods become more verbose (and some of the dependencies less obvious as they aren't visible in the constructor).
This is a viable approach, but it should be noted that it's a little different than what's described in Evans' book - where the idea was to be very deliberate about which aggregate roots should be obtained through repositories, and which via traversal, and under what circumstances - based on your understanding of the domain, business processes, access patterns, etc.
1 The two layers of interest here, in DDD terminology, are the Application Layer and the Domain Layer. The Application Layer ("defines the jobs the software is supposed to do and directs the expressive domain objects to work out problems") roughly corresponds to the Application Business Rules (Use Cases) layer in Clean Architecture ("use cases [...] direct [the] entities to use their enterprise wide business rules to achieve the goals of the use case").