How can I automatically set a post slug based on the post title during post publish?

As long as haven’t touched the slug WordPress will generate a new one after you entered a title.

Update

To change other peoples slugs use a filter (not tested!):

add_filter( 'wp_insert_post_data', 'prevent_numeric_slugs', 10, 1 );

function prevent_numeric_slugs( $post_data )
{
    if ( ! isset ( $post_data['post_title'] ) 
        or ! is_numeric( $post_data['post_name'] ) 
    )
    {   // exit early
        return $post_data;
    }

    // post_name is the slug
    $post_data['post_name'] = sanitize_title( $post_data['post_title'] );

    return $post_data;
}