@@ -131,6 +131,9 @@ function has_runner_step( array $steps ): bool {
131131 'steps ' => array ( array ( 'step ' => 'setSiteOptions ' , 'options ' => array ( 'description ' => 'Site artifact applied ' ) ) ),
132132 ),
133133 ),
134+ 'post_runtime_blueprint ' => array (
135+ 'steps ' => array ( array ( 'step ' => 'importWxr ' , 'file ' => 'https://example.test/first-caller.xml ' ) ),
136+ ),
134137 'include_internal_browser_session ' => true ,
135138);
136139
@@ -139,10 +142,17 @@ function has_runner_step( array $steps ): bool {
139142 fail ( 'preview failed: ' . $ preview ->get_error_code () . ': ' . $ preview ->get_error_message () );
140143}
141144$ hydrated = WP_Codebox_Abilities::hydrate_browser_blueprint_ref ( array ( 'ref ' => $ preview ['product ' ]['preview_boot ' ]['blueprint_ref ' ] ?? '' ) );
145+ $ second_input = $ input ;
146+ $ second_input ['sandbox_session_id ' ] = 'preview-only-session-second ' ;
147+ $ second_input ['post_runtime_blueprint ' ] = array (
148+ 'steps ' => array ( array ( 'step ' => 'importWxr ' , 'file ' => 'https://example.test/second-caller.xml ' ) ),
149+ );
150+ $ second = WP_Codebox_Abilities::create_browser_playground_session ( $ second_input + array ( 'preview_only ' => true ) );
151+ $ second_hydrated = WP_Codebox_Abilities::hydrate_browser_blueprint_ref ( array ( 'ref ' => $ second ['product ' ]['preview_boot ' ]['blueprint_ref ' ] ?? '' ) );
142152$ agentic = WP_Codebox_Abilities::create_browser_playground_session ( $ input );
143153$ task = WP_Codebox_Abilities::create_browser_task_contract ( $ input + array ( 'preview_only ' => true , 'include_internal_browser_contract ' => true ) );
144154
145- foreach ( array ( 'hydrated ' => $ hydrated , 'agentic ' => $ agentic , 'task ' => $ task ) as $ name => $ result ) {
155+ foreach ( array ( 'hydrated ' => $ hydrated , 'second ' => $ second , ' second_hydrated ' => $ second_hydrated , ' agentic ' => $ agentic , 'task ' => $ task ) as $ name => $ result ) {
146156 if ( is_wp_error ( $ result ) ) {
147157 fail ( $ name . ' failed: ' . $ result ->get_error_code () . ': ' . $ result ->get_error_message () );
148158 }
@@ -170,7 +180,16 @@ function has_runner_step( array $steps ): bool {
170180expect ( true === ( $ preview ['product ' ]['preview_boot ' ]['blueprint_ref_dto ' ]['hydratable ' ] ?? false ), 'Preview-only product DTO must expose a hydratable blueprint ref. ' );
171181
172182expect ( ! is_wp_error ( $ hydrated ), 'Preview-only prepared runtime blueprint ref must hydrate. ' );
173- expect ( $ preview ['playground ' ]['blueprint ' ] === ( $ hydrated ['blueprint ' ] ?? null ), 'Preview-only boot blueprint must be the cached executable runtime blueprint. ' );
183+ expect ( 'miss ' === ( $ preview ['runtime ' ]['prepared_runtime ' ]['status ' ] ?? '' ), 'First caller tail must materialize the shared runtime cache. ' );
184+ expect ( 'hit ' === ( $ second ['runtime ' ]['prepared_runtime ' ]['status ' ] ?? '' ), 'Second caller tail must reuse the shared runtime cache. ' );
185+ expect ( $ preview ['playground ' ]['blueprint ' ] === ( $ hydrated ['blueprint ' ] ?? null ), 'First caller hydration must return its executable blueprint. ' );
186+ expect ( $ second ['playground ' ]['blueprint ' ] === ( $ second_hydrated ['blueprint ' ] ?? null ), 'Second caller hydration must return its executable blueprint. ' );
187+ expect ( str_contains ( wp_json_encode ( $ hydrated ['blueprint ' ]['steps ' ] ?? array () ) ?: '' , 'first-caller.xml ' ), 'First caller hydration must retain its SSI import. ' );
188+ expect ( ! str_contains ( wp_json_encode ( $ hydrated ['blueprint ' ]['steps ' ] ?? array () ) ?: '' , 'second-caller.xml ' ), 'First caller hydration must not contain the second caller import. ' );
189+ expect ( str_contains ( wp_json_encode ( $ second_hydrated ['blueprint ' ]['steps ' ] ?? array () ) ?: '' , 'second-caller.xml ' ), 'Second caller hydration must retain its SSI import. ' );
190+ expect ( ! str_contains ( wp_json_encode ( $ second_hydrated ['blueprint ' ]['steps ' ] ?? array () ) ?: '' , 'first-caller.xml ' ), 'Second caller hydration must not contain the first caller import. ' );
191+ expect ( 'importWxr ' === ( $ hydrated ['blueprint ' ]['steps ' ][ count ( $ hydrated ['blueprint ' ]['steps ' ] ?? array () ) - 1 ]['step ' ] ?? '' ), 'First caller import must run after shared runtime steps. ' );
192+ expect ( 'importWxr ' === ( $ second_hydrated ['blueprint ' ]['steps ' ][ count ( $ second_hydrated ['blueprint ' ]['steps ' ] ?? array () ) - 1 ]['step ' ] ?? '' ), 'Second caller import must run after shared runtime steps. ' );
174193
175194expect ( false === ( $ agentic ['preview_only ' ] ?? true ), 'Default browser session must remain agentic. ' );
176195expect ( 'inherited-provider ' === ( $ agentic ['provider ' ] ?? '' ), 'Default browser session must retain provider inheritance. ' );
0 commit comments