Why does my deploy log say `No composer.lock file present` when I really do have a `composer.lock`?

I’m deploying a Drupal 8 or 9 site, and although things seem to work OK, my deploy log contains the confusing message:

Changed current directory to /app/.global/composer/composer
    W: No composer.lock file present. Updating dependencies to latest instead of installing from lock file.

And composer seems to be running twice.
I have committed a composer.lock file, and that should be getting used.
What’s going on?

Composer is being run twice, and the first time run is not in your application root, that’s why your applications composer.lock file is not being used.

This first run is a result of adding composer 2 as a PHP dependency , as recommended in the Platform.sh PHP build documentation.

dependencies:
    php:
        composer/composer: '^2'

When you define a PHP dependency like this, composer gets installed into a location on the system before your own app gets installed. composer 2 then gets used to do your actual application install, as requested.

Here, that location is the special directory /app/.global/.
/app/global/bin is also added to your $PATH so that composer will get executed from there.

This happens even when not specifying a composer flavored build

This will also take effect if you chose not to use composer

build:
    flavor: none

but still define a PHP dependency, such as

dependencies:
    php:
        drush/drush: "^8.0"

Dependencies get downloaded locally also

This can also be seen when running:

platform build

…on your local checkout of your code. In this case, the console will show a message like:

platform --verbose build
...
Building application app (runtime type: php:7.4)
Installing php dependencies with 'composer': composer/composer, drush/drush
Running command: 'command' '-v' 'composer'

Running command: composer install --no-progress --prefer-dist --optimize-autoloader --no-interaction
No composer.lock file present. Updating dependencies to latest instead of installing from lock file. See https://getcomposer.org/install for more information.
Loading composer repositories with package information
Updating dependencies
...

And a local copy of composer or drush may be installed into your .platform/local/deps/php/vendor/ directory.

Note that .platform/local/deps/php/vendor/bin is not automatically added to your local $PATH so these libraries may not be immediately available for use. You may want to resolve that yourself.