For terminology in Domain Driven Design, start from "the blue book" -- Domain Driven Design by Eric Evans.
AGGREGATE
A cluster of associated objects that are treated as a unit for the purpose of data changes. External references are restricted to one member of the aggregate, designated as the root. A set of consistency rules applies within the aggregate's boundaries.
That last sentence, I think you can turn around -- the boundaries of the aggregate are defined by the consistency rules.
It's definitely the case that an aggregate has state. Each time the domain model changes, an aggregate is taken from one consistent state to another. The data that we persist is used to reconstruct this state. So in that sense, it is a real thing.
But the aggregate itself doesn't necessarily have a word in the ubiquitous language. It's a derived concept.
Broadly, we could put the entire domain model under a single aggregate, that enforces all of the consistency rules. We don't, because it that design doesn't scale: we can't change the domain model two different ways at the same time, even when the changes we are making don't share any consistency rules. It's a poor way to model a business that can do more than one thing at a time.
Instead, we decompose the consistency rules into sets, subject to the constraint that two rules that reference the same data must be part of the same set. (In doing this, we are also working with the ubiquitous language and the domain experts to determine if we are correctly describing the consistency rules).
To update the model, we identify the aggregate responsible for a piece of data and propose the change. If the aggregate verifies all of its local consistency rules, we know that the change is globally valid, and we can apply the change. This restores our ability to do more than one thing at a time - changes to data in different aggregates can't possibly conflict with each other, by construction.
Best practices suggest that most aggregates should contain only the root entity. So you can conflate the aggregate with the entity without too much risk. But my guess it there won't usually be anything in the ubiquitous language to hang on the cluster when it includes more than one entity; so you end up with the ShoppingCart aggregate maintaining the consistency rules for the ShoppingCart entity and the CartItems entity collection and....
Partial loading of an aggregate is broken when trying to apply a change -- how could a well designed aggregate possible validate all of its consistency rules with a subset of the data? It's certainly the case that, if you have a requirement where this makes sense, your modeling is broken somewhere.
But if you are doing a read, loading only some of the data guarded by the aggregate can make sense. Command Query Responsibility Separation (CQRS) takes this a step further; once the model has verified that the data satisfies the consistency rules, you can completely rearrange that data into whatever read only form makes your life easiest. Put another way, if you aren't concerned with data changes, you don't need to worry about the aggregate boundary at all.
You may want to display the inventory level on the web page, or you may want to display the edition number of the inventory in stock (imagine your inventory is books, magazines etc). This information comes from the Inventory domain.
The main thing to notice at this point is that you are talking about a view, which is to say that using stale data is acceptable.
That being said, you don't need to be interacting with the aggregates (which are responsible for preventing changes from violating the business invariant), but with a representation of a recent copy of the aggregate's state.
So what I would normally expect is a query run against the Product Catalog, and another run against the Inventory, and something to compose the two into the DTO that you need to support the view.
Load both the Product domain and the Inventory domain aggregates?
So that's close. We don't need to load the aggregates, because we aren't going to change anything. But we need their state; so we could load that. That said, I would normally expect the two domains to be running in different processes. Therefore, we'd be calling both, not loading both.
Would you hold some properties on your Product domain entity for number in stock, and edition in stock, and then use Domain Events to update these when the Inventory entity is updated?
"Don't cross the streams. It would be bad."
Using events to coordinate information across domain contexts: great idea. Pushing concepts that belong in one domain into another: opposite of a great idea, except more so.
You want to keep the domains clean. The applications that interact with the domains, it's not so important. So for instance, it is reasonable for the Inventory application to call a service in the product application to query some product specific concepts to add to a view. Or vice versa.
I don't know of any reason that a single application needs to be restricted to a single domain. So long as there is a single source of truth, you can distribute the transactions any way you like.
But just to think this through, in the example above we would end up with potentially 2 DB tables for product catalog and product inventory. Now, do we use the same identifier in these as it's the same product.
That would be the easy way. In larger terms, you use the same identifier because the real world entity is the same; the two different bounded contexts model that entity differently, but the model isn't the real world entity.
When that doesn't work, then you'll need some query to use to bridge the gap. I think the most common variation of this is that the newer entity preserves the id of the older entity. You'll see this within a single BC as well: applicants, when approved, become clients. It's a different aggregate (the state associated with a client is subject to a different invariant than that of the applicant); so if your persistence layer is using event streams, the stream for the new aggregate will need a different identifier. So there will be a bit of state somewhere that says "this applicant became this client".
Or, could we use 1 table and 1 table row for the data and simply map the relevant data onto the aggregate properties?
YIKES! No, don't do that. You're adding transaction contention without any business reason for doing so.
Best Answer
You need to understand that DDD is not about primary keys, rows or tables - these are just means to implement it.
Aggregate root is usually implemented as a class, because you are expected to access all the functionality and data of the aggregate through the root. It therefore needs to have some behavior, something which primary key of the table can't have. Primary benefit of this is the encapsulation of aggregates - its logic is completely contained inside the aggregate and doesn't leak outside which greatly reduces the coupling (and as a consequence complexity) of the application.
It follows that each aggregate has its own aggregate root, so two aggregates can't have the same root (if they have, there is effectively just one aggregate).
In your case, you probably want to have two independent aggregates (ActiveEmployee, InactiveEmployee) which are backed by the same table (which is fine because it's totally out of DDD's scope). But then remember that there's actually no dbo.Employee entity in your domain model, it's just a table on a lower (persistence) layer.