run:R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
23.8 KB
2026-03-11 16:18:51
R W Run
7.8 KB
2026-03-11 16:18:52
R W Run
36.1 KB
2026-03-11 16:18:51
R W Run
11.9 KB
2026-03-11 16:18:52
R W Run
18.94 KB
2026-03-11 16:18:52
R W Run
7.35 KB
2026-03-11 16:18:52
R W Run
28.6 KB
2026-03-11 16:18:51
R W Run
316 By
2026-03-11 16:18:51
R W Run
12.9 KB
2026-03-11 16:18:51
R W Run
61.02 KB
2026-03-11 16:18:52
R W Run
15 KB
2026-03-11 16:18:51
R W Run
112.05 KB
2026-03-11 16:18:51
R W Run
12.47 KB
2026-03-11 16:18:51
R W Run
15.07 KB
2026-03-11 16:18:52
R W Run
9.84 KB
2026-03-11 16:18:52
R W Run
13.17 KB
2026-03-11 16:18:52
R W Run
33.83 KB
2026-03-11 16:18:51
R W Run
42.63 KB
2026-03-11 16:18:51
R W Run
55.71 KB
2026-03-11 16:18:52
R W Run
12.53 KB
2026-03-11 16:18:51
R W Run
2.55 KB
2026-03-11 16:18:52
R W Run
28.92 KB
2026-03-11 16:18:52
R W Run
539 By
2026-03-11 16:18:51
R W Run
367 By
2026-03-11 16:18:52
R W Run
42.65 KB
2026-03-11 16:18:51
R W Run
401 By
2026-03-11 16:18:51
R W Run
6.61 KB
2026-03-11 16:18:51
R W Run
664 By
2026-03-11 16:18:52
R W Run
20.63 KB
2026-03-11 16:18:51
R W Run
2.18 KB
2026-03-11 16:18:52
R W Run
453 By
2026-03-11 16:18:52
R W Run
457 By
2026-03-11 16:18:51
R W Run
36.83 KB
2026-03-11 16:18:52
R W Run
2.41 KB
2026-03-11 16:18:52
R W Run
8.28 KB
2026-03-11 16:18:51
R W Run
13.89 KB
2026-03-11 16:18:51
R W Run
11.76 KB
2026-03-11 16:18:51
R W Run
2.65 KB
2026-03-11 16:18:51
R W Run
7.43 KB
2026-03-11 16:18:51
R W Run
17.46 KB
2026-03-11 16:18:51
R W Run
5.14 KB
2026-03-11 16:18:52
R W Run
16.7 KB
2026-03-11 16:18:51
R W Run
8.28 KB
2026-03-11 16:18:52
R W Run
2.92 KB
2026-03-11 16:18:52
R W Run
1.32 KB
2026-03-11 16:18:51
R W Run
4.6 KB
2026-03-11 16:18:52
R W Run
11.62 KB
2026-03-11 16:18:52
R W Run
2.5 KB
2026-03-11 16:18:51
R W Run
1.97 KB
2026-03-11 16:18:51
R W Run
11.25 KB
2026-03-11 16:18:52
R W Run
5.32 KB
2026-03-11 16:18:51
R W Run
10.99 KB
2026-03-11 16:18:52
R W Run
68.32 KB
2026-03-11 16:18:51
R W Run
6.34 KB
2026-03-11 16:18:51
R W Run
5.49 KB
2026-03-11 16:18:51
R W Run
1.99 KB
2026-03-11 16:18:52
R W Run
7.02 KB
2026-03-11 16:18:51
R W Run
4.91 KB
2026-03-11 16:18:52
R W Run
16.86 KB
2026-03-11 16:18:51
R W Run
24.23 KB
2026-03-11 16:18:51
R W Run
3.97 KB
2026-03-11 16:18:51
R W Run
47.66 KB
2026-03-11 16:18:51
R W Run
9.22 KB
2026-03-11 16:18:51
R W Run
25.51 KB
2026-03-11 16:18:51
R W Run
198.38 KB
2026-03-11 16:18:52
R W Run
56.65 KB
2026-03-11 16:18:51
R W Run
10.46 KB
2026-03-11 16:18:51
R W Run
10.95 KB
2026-03-11 16:18:52
R W Run
29.26 KB
2026-03-11 16:18:51
R W Run
70.91 KB
2026-03-11 16:18:52
R W Run
35.3 KB
2026-03-11 16:18:52
R W Run
16.61 KB
2026-03-11 16:18:52
R W Run
2.57 KB
2026-03-11 16:18:52
R W Run
39.83 KB
2026-03-11 16:18:51
R W Run
70.64 KB
2026-03-11 16:18:51
R W Run
15.56 KB
2026-03-11 16:18:52
R W Run
7.33 KB
2026-03-11 16:18:52
R W Run
253 By
2026-03-11 16:18:51
R W Run
7.96 KB
2026-03-11 16:18:52
R W Run
3.23 KB
2026-03-11 16:18:52
R W Run
969 By
2026-03-11 16:18:52
R W Run
16.28 KB
2026-03-11 16:18:51
R W Run
7.22 KB
2026-03-11 16:18:51
R W Run
12.95 KB
2026-03-11 16:18:51
R W Run
6.53 KB
2026-03-11 16:18:51
R W Run
3.42 KB
2026-03-11 16:18:52
R W Run
5.84 KB
2026-03-11 16:18:51
R W Run
1.97 KB
2026-03-11 16:18:51
R W Run
4.3 KB
2026-03-11 16:18:52
R W Run
2.91 KB
2026-03-11 16:18:51
R W Run
16.46 KB
2026-03-11 16:18:52
R W Run
40.6 KB
2026-03-11 16:18:51
R W Run
20.22 KB
2026-03-11 16:18:51
R W Run
36.11 KB
2026-03-11 16:18:52
R W Run
17.01 KB
2026-03-11 16:18:51
R W Run
7.27 KB
2026-03-11 16:18:52
R W Run
6.62 KB
2026-03-11 16:18:52
R W Run
16.49 KB
2026-03-11 16:18:52
R W Run
1.79 KB
2026-03-11 16:18:52
R W Run
29.82 KB
2026-03-11 16:18:51
R W Run
6.67 KB
2026-03-11 16:18:52
R W Run
8.98 KB
2026-03-11 16:18:52
R W Run
19.42 KB
2026-03-11 16:18:51
R W Run
12.01 KB
2026-03-11 16:18:51
R W Run
17.11 KB
2026-03-11 16:18:51
R W Run
6.74 KB
2026-03-11 16:18:52
R W Run
30.93 KB
2026-03-11 16:18:51
R W Run
4.99 KB
2026-03-11 16:18:51
R W Run
4.25 KB
2026-03-11 16:18:51
R W Run
24.72 KB
2026-03-11 16:18:51
R W Run
29.96 KB
2026-03-11 16:18:52
R W Run
6.41 KB
2026-03-11 16:18:51
R W Run
160 KB
2026-03-11 16:18:51
R W Run
6.72 KB
2026-03-11 16:18:52
R W Run
10.92 KB
2026-03-11 16:18:51
R W Run
4.77 KB
2026-03-11 16:18:51
R W Run
3.38 KB
2026-03-11 16:18:51
R W Run
11.18 KB
2026-03-11 16:18:51
R W Run
62.19 KB
2026-03-11 16:18:51
R W Run
2.46 KB
2026-03-11 16:18:51
R W Run
9.17 KB
2026-03-11 16:18:51
R W Run
32.15 KB
2026-03-11 16:18:51
R W Run
34.05 KB
2026-03-11 16:18:52
R W Run
7.15 KB
2026-03-11 16:18:51
R W Run
3.47 KB
2026-03-11 16:18:52
R W Run
1.87 KB
2026-03-11 16:18:52
R W Run
30.91 KB
2026-03-11 16:18:51
R W Run
7.29 KB
2026-03-11 16:18:52
R W Run
7.35 KB
2026-03-11 16:18:51
R W Run
12.54 KB
2026-03-11 16:18:51
R W Run
19.12 KB
2026-03-11 16:18:51
R W Run
18.12 KB
2026-03-11 16:18:52
R W Run
39.99 KB
2026-03-11 16:18:52
R W Run
5.17 KB
2026-03-11 16:18:52
R W Run
979 By
2026-03-11 16:18:51
R W Run
18.44 KB
2026-03-11 16:18:52
R W Run
10.24 KB
2026-03-11 16:18:51
R W Run
1.77 KB
2026-03-11 16:18:52
R W Run
34.9 KB
2026-03-11 16:18:51
R W Run
7.19 KB
2026-03-11 16:18:52
R W Run
160.5 KB
2026-03-11 16:18:51
R W Run
64.27 KB
2026-03-11 16:18:51
R W Run
27.95 KB
2026-03-11 16:18:51
R W Run
4.69 KB
2026-03-11 16:18:51
R W Run
2.94 KB
2026-03-11 16:18:51
R W Run
43.13 KB
2026-03-11 16:18:52
R W Run
2.25 KB
2026-03-11 16:18:52
R W Run
22.5 KB
2026-03-11 16:18:51
R W Run
13.01 KB
2026-03-11 16:18:52
R W Run
3.27 KB
2026-03-11 16:18:51
R W Run
18 KB
2026-03-11 16:18:51
R W Run
210.4 KB
2026-03-11 16:18:52
R W Run
25.86 KB
2026-03-11 16:18:52
R W Run
115.85 KB
2026-03-11 16:18:51
R W Run
373 By
2026-03-11 16:18:52
R W Run
343 By
2026-03-11 16:18:52
R W Run
338 By
2026-03-11 16:18:51
R W Run
100.73 KB
2026-03-11 16:18:52
R W Run
130.93 KB
2026-03-11 16:18:51
R W Run
19.1 KB
2026-03-11 16:18:51
R W Run
17.41 KB
2026-03-11 16:18:52
R W Run
41.98 KB
2026-03-11 16:18:52
R W Run
400 By
2026-03-11 16:18:52
R W Run
11.1 KB
2026-03-11 16:18:52
R W Run
37.02 KB
2026-03-11 16:18:51
R W Run
2.24 KB
2026-03-11 16:18:51
R W Run
188.13 KB
2026-03-11 16:18:51
R W Run
338 By
2026-03-11 16:18:51
R W Run
38 KB
2026-03-11 16:18:51
R W Run
4.02 KB
2026-03-11 16:18:52
R W Run
5.38 KB
2026-03-11 16:18:51
R W Run
3.05 KB
2026-03-11 16:18:52
R W Run
2.61 KB
2026-03-11 16:18:51
R W Run
1.16 KB
2026-03-11 16:18:52
R W Run
4.04 KB
2026-03-11 16:18:51
R W Run
3.71 KB
2026-03-11 16:18:51
R W Run
24.6 KB
2026-03-11 16:18:51
R W Run
9.56 KB
2026-03-11 16:18:51
R W Run
346.43 KB
2026-03-11 16:18:52
R W Run
281.84 KB
2026-03-11 16:18:52
R W Run
14.95 KB
2026-03-11 16:18:51
R W Run
8.44 KB
2026-03-11 16:18:52
R W Run
168.95 KB
2026-03-11 16:18:52
R W Run
20.71 KB
2026-03-11 16:18:52
R W Run
25.27 KB
2026-03-11 16:18:51
R W Run
5.72 KB
2026-03-11 16:18:51
R W Run
4.63 KB
2026-03-11 16:18:52
R W Run
81.73 KB
2026-03-11 16:18:51
R W Run
67.18 KB
2026-03-11 16:18:51
R W Run
156.36 KB
2026-03-11 16:18:52
R W Run
55.19 KB
2026-03-11 16:18:51
R W Run
162 By
2026-03-11 16:18:51
R W Run
61.72 KB
2026-03-11 16:18:51
R W Run
216.06 KB
2026-03-11 16:18:52
R W Run
65.09 KB
2026-03-11 16:18:51
R W Run
25.24 KB
2026-03-11 16:18:52
R W Run
4.81 KB
2026-03-11 16:18:51
R W Run
6.48 KB
2026-03-11 16:18:52
R W Run
21.25 KB
2026-03-11 16:18:51
R W Run
2.79 KB
2026-03-11 16:18:52
R W Run
89.69 KB
2026-03-11 16:18:52
R W Run
19.42 KB
2026-03-11 16:18:52
R W Run
3.69 KB
2026-03-11 16:18:52
R W Run
4.11 KB
2026-03-11 16:18:51
R W Run
40.74 KB
2026-03-11 16:18:51
R W Run
25.38 KB
2026-03-11 16:18:51
R W Run
43.31 KB
2026-03-11 16:18:52
R W Run
102.57 KB
2026-03-11 16:18:52
R W Run
6.18 KB
2026-03-11 16:18:51
R W Run
124.47 KB
2026-03-11 16:18:52
R W Run
35.65 KB
2026-03-11 16:18:52
R W Run
6.94 KB
2026-03-11 16:18:52
R W Run
67.04 KB
2026-03-11 16:18:52
R W Run
10.62 KB
2026-03-11 16:18:51
R W Run
289.35 KB
2026-03-11 16:18:52
R W Run
36.23 KB
2026-03-11 16:18:51
R W Run
200 By
2026-03-11 16:18:52
R W Run
200 By
2026-03-11 16:18:52
R W Run
98.29 KB
2026-03-11 16:18:52
R W Run
30.02 KB
2026-03-11 16:18:52
R W Run
19.03 KB
2026-03-11 16:18:52
R W Run
5.06 KB
2026-03-11 16:18:52
R W Run
255 By
2026-03-11 16:18:51
R W Run
22.66 KB
2026-03-11 16:18:52
R W Run
154.63 KB
2026-03-11 16:18:51
R W Run
9.68 KB
2026-03-11 16:18:51
R W Run
258 By
2026-03-11 16:18:51
R W Run
23.49 KB
2026-03-11 16:18:51
R W Run
3.16 KB
2026-03-11 16:18:51
R W Run
8.4 KB
2026-03-11 16:18:52
R W Run
441 By
2026-03-11 16:18:51
R W Run
7.39 KB
2026-03-11 16:18:51
R W Run
173 KB
2026-03-11 16:18:52
R W Run
544 By
2026-03-11 16:18:52
R W Run
4.17 KB
2026-03-11 16:18:51
R W Run
35.97 KB
2026-03-11 16:18:52
R W Run
1.69 KB
2026-03-11 16:18:51
R W Run
2.84 KB
2026-03-11 16:18:52
R W Run
6.09 KB
2026-03-11 16:18:51
R W Run
8.71 KB
2026-03-11 16:18:51
R W Run
131.84 KB
2026-03-11 16:18:51
R W Run
37.45 KB
2026-03-11 16:18:51
R W Run
173.89 KB
2026-03-11 16:18:51
R W Run
7.09 KB
2026-03-11 16:18:51
R W Run
6.41 KB
2026-03-11 16:18:51
R W Run
1.08 KB
2026-03-11 16:18:51
R W Run
69.46 KB
2026-03-11 16:18:52
R W Run
445 By
2026-03-11 16:18:51
R W Run
799 By
2026-03-11 16:18:52
R W Run
error_log
📄class-wp-speculation-rules.php
1<?php
2/**
3 * Class 'WP_Speculation_Rules'.
4 *
5 * @package WordPress
6 * @subpackage Speculative Loading
7 * @since 6.8.0
8 */
9
10/**
11 * Class representing a set of speculation rules.
12 *
13 * @since 6.8.0
14 * @access private
15 */
16final class WP_Speculation_Rules implements JsonSerializable {
17
18 /**
19 * Stored rules, as a map of `$mode => $rules` pairs.
20 *
21 * Every `$rules` value is a map of `$id => $rule` pairs.
22 *
23 * @since 6.8.0
24 * @var array<string, array<string, mixed>>
25 */
26 private $rules_by_mode = array();
27
28 /**
29 * The allowed speculation rules modes as a map, used for validation.
30 *
31 * @since 6.8.0
32 * @var array<string, bool>
33 */
34 private static $mode_allowlist = array(
35 'prefetch' => true,
36 'prerender' => true,
37 );
38
39 /**
40 * The allowed speculation rules eagerness levels as a map, used for validation.
41 *
42 * @since 6.8.0
43 * @var array<string, bool>
44 */
45 private static $eagerness_allowlist = array(
46 'immediate' => true,
47 'eager' => true,
48 'moderate' => true,
49 'conservative' => true,
50 );
51
52 /**
53 * The allowed speculation rules sources as a map, used for validation.
54 *
55 * @since 6.8.0
56 * @var array<string, bool>
57 */
58 private static $source_allowlist = array(
59 'list' => true,
60 'document' => true,
61 );
62
63 /**
64 * Adds a speculation rule to the speculation rules to consider.
65 *
66 * @since 6.8.0
67 *
68 * @param string $mode Speculative loading mode. Either 'prefetch' or 'prerender'.
69 * @param string $id Unique string identifier for the speculation rule.
70 * @param array<string, mixed> $rule Associative array of rule arguments.
71 * @return bool True on success, false if invalid parameters are provided.
72 */
73 public function add_rule( string $mode, string $id, array $rule ): bool {
74 if ( ! self::is_valid_mode( $mode ) ) {
75 _doing_it_wrong(
76 __METHOD__,
77 sprintf(
78 /* translators: %s: invalid mode value */
79 __( 'The value "%s" is not a valid speculation rules mode.' ),
80 esc_html( $mode )
81 ),
82 '6.8.0'
83 );
84 return false;
85 }
86
87 if ( ! $this->is_valid_id( $id ) ) {
88 _doing_it_wrong(
89 __METHOD__,
90 sprintf(
91 /* translators: %s: invalid ID value */
92 __( 'The value "%s" is not a valid ID for a speculation rule.' ),
93 esc_html( $id )
94 ),
95 '6.8.0'
96 );
97 return false;
98 }
99
100 if ( $this->has_rule( $mode, $id ) ) {
101 _doing_it_wrong(
102 __METHOD__,
103 sprintf(
104 /* translators: %s: invalid ID value */
105 __( 'A speculation rule with ID "%s" already exists.' ),
106 esc_html( $id )
107 ),
108 '6.8.0'
109 );
110 return false;
111 }
112
113 /*
114 * Perform some basic speculation rule validation.
115 * Every rule must have either a 'where' key or a 'urls' key, but not both.
116 * The presence of a 'where' key implies a 'source' of 'document', while the presence of a 'urls' key implies
117 * a 'source' of 'list'.
118 */
119 if (
120 ( ! isset( $rule['where'] ) && ! isset( $rule['urls'] ) ) ||
121 ( isset( $rule['where'] ) && isset( $rule['urls'] ) )
122 ) {
123 _doing_it_wrong(
124 __METHOD__,
125 sprintf(
126 /* translators: 1: allowed key, 2: alternative allowed key */
127 __( 'A speculation rule must include either a "%1$s" key or a "%2$s" key, but not both.' ),
128 'where',
129 'urls'
130 ),
131 '6.8.0'
132 );
133 return false;
134 }
135 if ( isset( $rule['source'] ) ) {
136 if ( ! self::is_valid_source( $rule['source'] ) ) {
137 _doing_it_wrong(
138 __METHOD__,
139 sprintf(
140 /* translators: %s: invalid source value */
141 __( 'The value "%s" is not a valid source for a speculation rule.' ),
142 esc_html( $rule['source'] )
143 ),
144 '6.8.0'
145 );
146 return false;
147 }
148
149 if ( 'list' === $rule['source'] && isset( $rule['where'] ) ) {
150 _doing_it_wrong(
151 __METHOD__,
152 sprintf(
153 /* translators: 1: source value, 2: forbidden key */
154 __( 'A speculation rule of source "%1$s" must not include a "%2$s" key.' ),
155 'list',
156 'where'
157 ),
158 '6.8.0'
159 );
160 return false;
161 }
162
163 if ( 'document' === $rule['source'] && isset( $rule['urls'] ) ) {
164 _doing_it_wrong(
165 __METHOD__,
166 sprintf(
167 /* translators: 1: source value, 2: forbidden key */
168 __( 'A speculation rule of source "%1$s" must not include a "%2$s" key.' ),
169 'document',
170 'urls'
171 ),
172 '6.8.0'
173 );
174 return false;
175 }
176 }
177
178 // If there is an 'eagerness' key specified, make sure it's valid.
179 if ( isset( $rule['eagerness'] ) ) {
180 if ( ! self::is_valid_eagerness( $rule['eagerness'] ) ) {
181 _doing_it_wrong(
182 __METHOD__,
183 sprintf(
184 /* translators: %s: invalid eagerness value */
185 __( 'The value "%s" is not a valid eagerness for a speculation rule.' ),
186 esc_html( $rule['eagerness'] )
187 ),
188 '6.8.0'
189 );
190 return false;
191 }
192
193 if ( isset( $rule['where'] ) && 'immediate' === $rule['eagerness'] ) {
194 _doing_it_wrong(
195 __METHOD__,
196 sprintf(
197 /* translators: %s: forbidden eagerness value */
198 __( 'The eagerness value "%s" is forbidden for document-level speculation rules.' ),
199 'immediate'
200 ),
201 '6.8.0'
202 );
203 return false;
204 }
205 }
206
207 if ( ! isset( $this->rules_by_mode[ $mode ] ) ) {
208 $this->rules_by_mode[ $mode ] = array();
209 }
210
211 $this->rules_by_mode[ $mode ][ $id ] = $rule;
212 return true;
213 }
214
215 /**
216 * Checks whether a speculation rule for the given mode and ID already exists.
217 *
218 * @since 6.8.0
219 *
220 * @param string $mode Speculative loading mode. Either 'prefetch' or 'prerender'.
221 * @param string $id Unique string identifier for the speculation rule.
222 * @return bool True if the rule already exists, false otherwise.
223 */
224 public function has_rule( string $mode, string $id ): bool {
225 return isset( $this->rules_by_mode[ $mode ][ $id ] );
226 }
227
228 /**
229 * Returns the speculation rules data ready to be JSON-encoded.
230 *
231 * @since 6.8.0
232 *
233 * @return array<string, array<string, mixed>> Speculation rules data.
234 */
235 #[ReturnTypeWillChange]
236 public function jsonSerialize() {
237 // Strip the IDs for JSON output, since they are not relevant for the Speculation Rules API.
238 return array_map(
239 static function ( array $rules ) {
240 return array_values( $rules );
241 },
242 array_filter( $this->rules_by_mode )
243 );
244 }
245
246 /**
247 * Checks whether the given ID is valid.
248 *
249 * @since 6.8.0
250 *
251 * @param string $id Unique string identifier for the speculation rule.
252 * @return bool True if the ID is valid, false otherwise.
253 */
254 private function is_valid_id( string $id ): bool {
255 return (bool) preg_match( '/^[a-z][a-z0-9_-]+$/', $id );
256 }
257
258 /**
259 * Checks whether the given speculation rules mode is valid.
260 *
261 * @since 6.8.0
262 *
263 * @param string $mode Speculation rules mode.
264 * @return bool True if valid, false otherwise.
265 */
266 public static function is_valid_mode( string $mode ): bool {
267 return isset( self::$mode_allowlist[ $mode ] );
268 }
269
270 /**
271 * Checks whether the given speculation rules eagerness is valid.
272 *
273 * @since 6.8.0
274 *
275 * @param string $eagerness Speculation rules eagerness.
276 * @return bool True if valid, false otherwise.
277 */
278 public static function is_valid_eagerness( string $eagerness ): bool {
279 return isset( self::$eagerness_allowlist[ $eagerness ] );
280 }
281
282 /**
283 * Checks whether the given speculation rules source is valid.
284 *
285 * @since 6.8.0
286 *
287 * @param string $source Speculation rules source.
288 * @return bool True if valid, false otherwise.
289 */
290 public static function is_valid_source( string $source ): bool {
291 return isset( self::$source_allowlist[ $source ] );
292 }
293}
294