ViewModel Architecture and
Clean Architecture are not the same.
In some ways they are incompatible. Please don't mix them carelessly.
The number one thing that separates them is cycles. ViewModel architecture is comfortable creating cycles in it's design. Clean (or Onion, or Hex) Architecture is not. ViewModel uses a binder to resolve the problems this can cause. Clean expects you to follow the Dependency Inversion Principle, make external layers swap-able plugins, and for you to do your binding yourself.
I'd go on but I've talked about this before. From here I'll just assume the ViewModel was a stray idea we can ignore.
In the Clean Architecture the Presentation layer and the Domain Model layer are separated by the Application layer. I understand how this make sense for stateless applications, like a Web base MVC application or a "record based" desktop application where most operations are CRUD. Also, my understanding is that the Presentation layer should not directly use the domain object, but should have it's own ViewModel that are mapped to/from models from the application layer. Is this assumption correct?
Many of these other terms aren't from Clean Architecture either. They are from Onion Architecture.
Here I mind the conflation much less because as Uncle Bob has admitted Clean Architecture explicitly lifts many of it's ideas and structure from Onion Architecture (which does the same from Hex / Ports and Adapters). It's all much the same idea with different buzz words that drive you to different blogs & books.
So as you were saying:
Presentation layer and the Domain Model layer are separated by the Application layer.
Yes, if by "domain" you mean Clean Architecture's Entities and by "Application layer" you mean Clean's Application Business Rules (Use Cases) and not OSIs Application layer.
Just be aware some people may map Onions domain onto both Cleans Entities and Use Cases. That doesn't mean separation logic isn't still a good idea. We're literally arguing semantics here.
So I'd say your assumption is correct. If I'm decoding your meaning correctly.
The application I plan to develop will allow the user to input chess games one move at a time. It seems to me that the rules for chess should be in the Domain Model layer.
I can agree with that.
... how does the Presentation layer validate each user input (to verify each moves legality)? Does it need to go through the Application Layer every time or does it makes more sense to let the Presentation Layer somehow manipulate the Domain objects directly to build the model according to the user input and then send it to the Application layer when it's time to save it to the database?
Validation often seems like it should happen in one place but this rarely works well. The reason is what's valid for one object isn't valid for another. Each object is meant to be an expert on its own thing. You could force it to happen in one place that must consider the whole application but consider this: The board knows how big it is. It doesn't know we're using it to play chess. Should the board assume chess will keep it safe or should the board say loudly "I'm only an 8 by 8 board. I don't know where to put this crazy 9,9 move you just made". Design the board like that and you can use its code to play checkers, tic tac toe, and go without teaching the board anything about those games.
I'd recommend letting the board validate against board issues and the game validate against game issues. And I'd consider both of these part of the "domain".
I tried to find resources online that would talk about this, but it seems all example/course/tutorial I found talk about a web application or at least a stateless application of the CRUD type where the business rules are applied once before saving the data or after loading them. In my application the chess rules needs to be applied every time the user edit the ViewModel to give an immediate feedback.
IO is slow. I might not be that good at speed chess but I still don't like the idea of sending moves directly to IO. Moves should go to memory first. But only after they've been validated.
One thing to understand here is that validation doesn't have to be enforced with exceptions. Every move is an attempt to change state. Not every move should result in a change of state. Every move should result in the user receiving feedback. So long as the validating object can provide that feedback in some way it's fine to shut down the attempt to change state.
And that brings me to output ports. One of the nifty things about Clean Architecture plugins is that despite everything being nicely a-cyclic, which keeps source code changes from propagating through your code base, you can still send the flow of control anywhere!
That works because of this little trick:
That open arrow head between Presenter and Use Case Output Port is asking for some kind of polymorphism. As long as you can provide that you can let info flow to anywhere you need it to and still ensure your architecture is a-cyclic.
(As I wrote this, the rubber duck effect kicked in and I now think that maybe I should always go through the application layer. I would still like to know what more experienced people think)
Sure, so long as that's the only place validators live. It's where I'd put them.
I'd tell you more about Clean Architecture and Chess but, well, I've also talked about that before.
In fact, I've talked about this a lot.