Three interrelated issues here:

- [ ] `TransportBroadcastByNodeAction` derivatives are typically executed via `NodeClient` which bypasses the `TransportService` and therefore does not respect (or even know about) the `executor` parameter which would fork. This means that the coordination work, including grouping all the shards by node, happens on the calling thread. When executed from the REST layer, that's a transport worker. This is #97916, but until that's fixed we need a workaround.

- [ ] The node-level responses are deserialised and processed on the receiving transport worker too.

- [ ] Several of these actions use `SAME` for their executor, bypassing the forking that _does_ exist today.

Relates #77466 
server/src/main/java/org/elasticsearch/action/support/broadcast/node/TransportBroadcastByNodeAction.java
* @param successfulShards the total number of shards for which execution of the operation was successful
         * @param failedShards     the total number of shards for which execution of the operation failed
         * @param results          the per-node aggregated shard-level results
         * @param shardFailures    the exceptions corresponding to shard operation failures
         * @return the response
         */
        Response newResponse(
            int totalShards,
            int successfulShards,
            int failedShards,
            List<ShardOperationResult> results,
            List<DefaultShardOperationFailedException> shardFailures
        );
    }
    /**
     * Create a response factory based on the requst and the cluster state captured at the time the request was handled. Implementations
     * must avoid capturing the full cluster state if possible.
     */
    protected abstract ResponseFactory<Response, ShardOperationResult> getResponseFactory(Request request, ClusterState clusterState);
    /**
     * Deserialize a request from an input stream
     *
     * @param in input stream
     * @return a de-serialized request
     */
    protected abstract Request readRequestFrom(StreamInput in) throws IOException;
    /**
     * Executes the shard-level operation. This method is called once per shard serially on the receiving node.
     * This method should not throw an exception, but pass the exception to the listener instead.
     *