You have to replace $post_id with get_the_id();
function status_alerts($query) { //start function
global $post; // set the global
$args = array( // all posts in the status post format
'posts_per_page' => -1,
'taxonomy' => 'post_format',
'field' => 'slug',
'terms' => array( 'post-format-status' ),
'operator'=> 'IN'
);
$alert_query = new WP_Query( $args ); while ( $alert_query->have_posts() ) : $alert_query->the_post(); //query post
if (get_post_meta( get_the_ID(), 'breaking_news_status', true ) == 'active') { // if the post has a meta field called 'active'
if ((get_post_meta(get_the_ID(), 'status_time_duration', true) + + get_the_time('U')) < date( 'U', current_time( 'timestamp', 0 ) )) { // if the 'status_time_duration' plus the publish date is greater than the current time
update_post_meta(get_the_ID(), 'breaking_news_status', 'archive'); // add a check to 'archive' to 'breaking_news_status'
}
}
endwhile;
wp_reset_query();
}