Is there any documentation on this formulation of ECS? I realize it's basically a different way of doing the same thing, but there are always important subtleties that emerge sooner or later.
That depends greatly on what you mean by "documentation." There are various GDC talks, blog posts and forum posts that explain the pattern. From a quick google search, it looks like they're being drowned out by articles based on the current Wiki article on ECS (or whatever that's based on), which advocates the approach where the components are stored separately from systems - and in all fairness, that IS more or less the only difference, but one that has big consequences on design.I'm not aware of any journal papers or the like. :)
This article has a brief overview of the different ECS variants. The one I'm advocating here is closest to Adam Martin's formulation as described therein (but weirdly not as Martin writes?).
Mike Acton's CppCon talk touches on some related concepts, but doesn't advocate "strict" ECS.
It's hard to find good sources on an arbitrary implementation of ECS because ECS is not a well-defined term. It's a group of related design patterns with subtle differences between them, some of which are more popular than others. I might be mistaken, so my formulation may not be the original, either, but it's the first one I remember seeing.
One question that arises is that if the components themselves are inside systems... Is it actually possible to create entities without knowledge of specific systems? In the "components live outside and are just data" formulation, the components are directly specified by whoever's creating the entity, without any specific knowledge of which systems will eventually process the components.
This isn't an important difference. Knowing about the components is functionally equivalent to knowing about the systems that own the components. This is true regardless - even if the components are stored outside the systems, they're still stored somewhere, and your creation logic needs to know about that place.
The important difference is that having the components be owned by the system allows other systems to not know about other systems' components directly. Remember, in a "pure ECS" of this type, all access to a component is gated through the system that owns the components of that type. All behaviour associated directly with the component is on the system that owns it. It gets a little funky when you have behaviour that affects two components that doesn't belong on a specific system, but this problem happens with "regular" OOP, too - and it's solved much the same way, by using free functions or creating another component type.
In my own code, the component structure definitions are usually private to the system that owns them. Other systems don't even know that those systems' component
types exist, never mind being able to access them. On the other hand, I don't use strict ECS, and I actually think putting yourself in a box with strict ECS is counter-productive if you want to write clean code that is also shippable. If you really want strict ECS, it's probably best not to overarchitect it.