$c['pass'] ) );
return (int) round( ( $passed / count( $checks ) ) * 10 );
}
/**
* Get all readiness checks.
*
* @return array
*/
public static function get_checks( array $settings, bool $may_measure = false ): array {
$checks = [
[
// Asks the URL, not the disk. The document is served from
// memory when there is no file, so "is there a file" answered
// the wrong question in both directions: it failed sites that
// work and passed sites whose web server never routes
// /.well-known/ to WordPress at all.
'label' => __( 'agents.json reachable', 'ai-ready-wp' ),
'pass' => $settings['enable_agents_json'] && AIREWP_Endpoint_Check::is_working( '.well-known/agents.json', $settings, $may_measure ),
],
[
'label' => __( 'agent-card.json reachable', 'ai-ready-wp' ),
'pass' => $settings['enable_agent_card'] && AIREWP_Endpoint_Check::is_working( '.well-known/agent-card.json', $settings, $may_measure ),
],
[
// Same question as for the JSON documents: llms.txt answers
// from a cache when there is no file (since 4.4.4).
'label' => __( 'llms.txt reachable', 'ai-ready-wp' ),
'pass' => $settings['enable_llms_txt'] && AIREWP_Endpoint_Check::is_working( 'llms.txt', $settings, $may_measure ),
],
[
'label' => __( 'JSON-LD schemas enabled', 'ai-ready-wp' ),
'pass' => (bool) $settings['enable_json_ld'],
],
[
// Allowed, not merely managed. Until 4.4.2 this check passed
// for a robots.txt that blocked GPTBot and ClaudeBot, which is
// the opposite of what the score claims to measure.
//
// And since 4.5.2 it asks the URL as well, for the same reason
// the JSON documents do. Everything above is about intent, and
// intent was all this check ever saw: robots.txt is written
// through a WordPress filter, so a static file in the site root
// or another plugin answering first leaves every setting saying
// yes while none of it reaches a crawler. Measured on a live
// site: full marks here, and a served robots.txt with no
// crawler group, no content signal and no discovery pointer in
// it. An unreachable check counts as working, as everywhere
// else here.
'label' => __( 'AI crawlers allowed in robots.txt', 'ai-ready-wp' ),
'pass' => ! empty( $settings['enable_robots_ai'] )
&& empty( $settings['robots_block_training'] )
&& empty( $settings['robots_block_retrieval'] )
&& AIREWP_Endpoint_Check::is_working( 'robots.txt', $settings, $may_measure ),
],
[
'label' => __( 'Company name set', 'ai-ready-wp' ),
'pass' => ! empty( $settings['company_name'] ),
],
[
'label' => __( 'Description set', 'ai-ready-wp' ),
'pass' => ! empty( $settings['company_desc'] ),
],
[
'label' => __( 'Contact email set', 'ai-ready-wp' ),
'pass' => ! empty( $settings['company_email'] ),
],
[
'label' => __( 'Services defined', 'ai-ready-wp' ),
'pass' => ! empty( $settings['services'] ),
],
[
'label' => __( 'Logo URL set', 'ai-ready-wp' ),
'pass' => ! empty( $settings['company_logo'] ),
],
[
'label' => __( 'IndexNow enabled', 'ai-ready-wp' ),
'pass' => $settings['enable_indexnow'] && ! empty( $settings['indexnow_key'] ),
],
];
// Only counted once the feature is on. A site without MCP servers has
// nothing to publish and must not lose a point for it; a site that
// switched the feature on has to list at least one server, otherwise
// it published an empty manifest for a full score, which is what the
// old check rewarded.
if ( ! empty( $settings['enable_mcp_json'] ) ) {
$checks[] = [
'label' => __( 'MCP servers published', 'ai-ready-wp' ),
'pass' => AIREWP_MCP_JSON::is_active( $settings )
&& AIREWP_Endpoint_Check::is_working( '.well-known/mcp.json', $settings, $may_measure ),
];
}
return $checks;
}
public static function get_score_message( int $score ): string {
if ( $score >= 9 ) {
return __( 'Excellent! Your site is fully AI-ready.', 'ai-ready-wp' );
}
if ( $score >= 7 ) {
return __( 'Good — a few items left to complete.', 'ai-ready-wp' );
}
if ( $score >= 4 ) {
return __( 'Getting there — fill in the missing settings.', 'ai-ready-wp' );
}
return __( 'Just getting started — configure your settings to improve.', 'ai-ready-wp' );
}
public static function get_score_color( int $score ): string {
if ( $score >= 8 ) {
return '#46b450';
}
if ( $score >= 5 ) {
return '#f0b849';
}
return '#dc3232';
}
}