How is composer including a dependent module? I have a composer managed Drupal project based on drupal/recommended-project.
I'm installing a contrib module, domain_group, and I'm seeing that composer is auto-including a required dependency, even though it's not listed in the module's composer.json. (I'm checking some other contrib modules and it seems that this is not specific to this module, but a consistent pattern across many modules.)
I run:
composer require drupal/domain_group

and it installs domain_group and domain_site_settings.
Then when I run:
composer why drupal/domain_site_settings

and it tells me that drupal/domain_group requires it.
While the dependency is not listed in domain_group/composer.json, I do see that it is listed in domain_group.info.yml.
Is composer somehow looking to the .info.yml to check for dependencies? Is this some kind of Drupal magic? What causes this? How does it work?
Update:
It seems that it's not checking the .info.yml, at least not locally. From @Clive, in the comments:

[composer why still lists the dependency] even when [the reference to domain_site_settings] is not in domain_group's local composer.json, composer.lock is deleted, the require line in domain_group.info.yml is commented out and composer cache is cleared (just checked). Where is it getting the reference?

I'm now wondering if composer why checks the remote repositories, e.g. https://packages.drupal.org/8, and if there's something special about the d.o repository that compiles extra package dependencies from .info.yml files.
domain_group/composer.json
{
    &quot;name&quot;: &quot;drupal/domain_group&quot;,
    &quot;type&quot;: &quot;drupal-module&quot;,
    &quot;description&quot;: &quot;This module provides integration between Domain and Group modules&quot;,
    &quot;homepage&quot;: &quot;http://drupal.org/project/domain_group&quot;,
    &quot;authors&quot;: [], // etc... 
    &quot;support&quot;: {}, // etc...
    &quot;license&quot;: &quot;GPL-2.0+&quot;,
    &quot;minimum-stability&quot;: &quot;dev&quot;,
    &quot;require&quot;: {
        &quot;drupal/core&quot;: &quot;^8.8 || ^9&quot;,
        &quot;drupal/group&quot;: &quot;~1.0&quot;,
        &quot;drupal/domain&quot;: &quot;~1.0&quot;
    }
}

domain_group/domain_group.info.yml
name: 'Domain Group'
type: module
description: 'This module provides integration between Domain and Group modules.'
core: 8.x
core_version_requirement: ^8 || ^9
package: 'Domain'
dependencies:
  - group:group
  - domain:domain
  - domain_site_settings:domain_site_settings # Is composer somehow respecting this?
I think this is what's happening:

The Drupal packager gets dependencies from domain_group.info.yml, and adds them to the dependencies for the package record that composer will use.
When composer installs the package, it downloads the current version of the module code (which doesn't have the dependency in composer.json)
Composer doesn't use that composer.json for its record keeping - it stores the dependency from the packager in composer.lock, and also in vendor/composer/installed.json
composer why seems to use composer.lock first for its info, falling back to installed.json if unavailable.

So it doesn't really matter what's in the module's composer.json as far as Composer commands are concerned - it's looking at composer.lock or installed.json, which has domain_site_settings as a requirement from the original install.