@@ -94,6 +94,64 @@ async function chipText(page) {
9494 return ( await page . locator ( ".personal-execution-chip" ) . innerText ( ) ) . replace ( / \s + / g, " " ) . trim ( ) ;
9595}
9696
97+ const pickerSelector = "div.personal-agent-select button.personal-select-trigger" ;
98+
99+ async function readPickerLabel ( page ) {
100+ return ( await page . locator ( pickerSelector ) . innerText ( ) ) . replace ( / \s + / g, " " ) . trim ( ) ;
101+ }
102+
103+ // What the page resolved, phrased so a failed CI run is diagnosable without a
104+ // local reproduction: the declared endpoint, the adapters the page actually
105+ // received and the label it rendered are the three facts that decide the label.
106+ async function pickerResolution ( page ) {
107+ const capabilities = await page . evaluate ( async ( ) => {
108+ try {
109+ const response = await fetch ( "/api/chat/capabilities" ) ;
110+ const body = await response . json ( ) ;
111+ return {
112+ status : response . status ,
113+ declaredEndpoint : body . manager ?. channel_binding ?. executor_endpoint ?? null ,
114+ adapters : ( body . adapters ?? [ ] ) . map (
115+ ( adapter ) => `${ adapter . agent_id } :${ adapter . available ? "available" : "unavailable" } ` ,
116+ ) ,
117+ } ;
118+ } catch ( error ) {
119+ return { status : "unavailable" , declaredEndpoint : null , adapters : [ ] , error : String ( error ) } ;
120+ }
121+ } ) ;
122+ return [
123+ `label=${ await readPickerLabel ( page ) } ` ,
124+ `declared=${ capabilities . declaredEndpoint ?? "<none>" } ` ,
125+ `adapters=[${ capabilities . adapters . join ( ", " ) } ]` ,
126+ `capabilities=${ capabilities . status } ${ capabilities . error ? ` (${ capabilities . error } )` : "" } ` ,
127+ ] . join ( " " ) ;
128+ }
129+
130+ // The picker resolves from the same capabilities response that carries the
131+ // channel binding, and the execution chip only renders once that binding
132+ // lands. A single read therefore asserts on a state the page never promised was
133+ // settled, and it can still hold the pre-fetch Codex fallback. Wait for the
134+ // declared value instead, and name what the page really resolved if the wait
135+ // runs out.
136+ async function waitForPickerLabel ( page , settled , timeoutMs = 15_000 ) {
137+ const deadline = Date . now ( ) + timeoutMs ;
138+ let label = await readPickerLabel ( page ) ;
139+ while ( ! settled ( label ) && Date . now ( ) < deadline ) {
140+ await page . waitForTimeout ( 100 ) ;
141+ label = await readPickerLabel ( page ) ;
142+ }
143+ if ( settled ( label ) ) {
144+ return label ;
145+ }
146+ const resolution = await pickerResolution ( page ) ;
147+ await page . screenshot ( {
148+ animations : "disabled" ,
149+ fullPage : false ,
150+ path : resolve ( outputDir , "execution-chip-picker-unresolved.png" ) ,
151+ } ) ;
152+ throw new Error ( `Chat runtime picker never settled: ${ resolution } ` ) ;
153+ }
154+
97155async function assertHairlineRow ( page ) {
98156 const headerBox = await page . locator ( ".personal-channel-header" ) . boundingBox ( ) ;
99157 const chipBox = await page . locator ( ".personal-execution-chip" ) . boundingBox ( ) ;
@@ -214,12 +272,10 @@ export const executionChipScenario = {
214272 collectCoverage,
215273 } ) ;
216274 try {
217- const pickerLabel = ( await stewardPicker . page
218- . locator ( "div.personal-agent-select button.personal-select-trigger" )
219- . innerText ( ) ) . replace ( / \s + / g, " " ) . trim ( ) ;
220- if ( ! pickerLabel . includes ( "DeepSeek Harness (managed)" ) ) {
221- throw new Error ( `Chat runtime picker ignored the declared steward executor: ${ pickerLabel } ` ) ;
222- }
275+ const pickerLabel = await waitForPickerLabel (
276+ stewardPicker . page ,
277+ ( label ) => label . includes ( "DeepSeek Harness (managed)" ) ,
278+ ) ;
223279 if ( pickerLabel . includes ( "Codex" ) ) {
224280 throw new Error ( `Chat runtime picker advertised a discovered CLI as the steward: ${ pickerLabel } ` ) ;
225281 }
@@ -242,12 +298,9 @@ export const executionChipScenario = {
242298 collectCoverage,
243299 } ) ;
244300 try {
245- const pickerLabel = ( await undeclaredSteward . page
246- . locator ( "div.personal-agent-select button.personal-select-trigger" )
247- . innerText ( ) ) . replace ( / \s + / g, " " ) . trim ( ) ;
248- if ( pickerLabel !== "Chat Codex" ) {
249- throw new Error ( `An undeclared steward executor no longer used the shipped default: ${ pickerLabel } ` ) ;
250- }
301+ // The shipped default is the settled value a machine with no declared
302+ // steward executor must keep.
303+ await waitForPickerLabel ( undeclaredSteward . page , ( label ) => label === "Chat Codex" ) ;
251304 } finally {
252305 coverageEntries . push ( ...await undeclaredSteward . close ( ) ) ;
253306 }
0 commit comments