@@ -382,6 +382,8 @@ export interface ResolveEffortForRoleOpts {
382382 roleDefault ?: ReasoningEffort ;
383383 /** Parent session effort — used only when the role default is not supported. */
384384 parentEffort ?: ReasoningEffort ;
385+ /** Marker when the parent effort was operator-chosen (see SubAgentProvider). */
386+ explicitParentEffort ?: true ;
385387 model : string ;
386388 isCodex ?: boolean ;
387389 providerEfforts ?: readonly ReasoningEffort [ ] ;
@@ -393,10 +395,12 @@ export interface ResolveEffortForRoleOpts {
393395 *
394396 * Precedence (first match wins):
395397 * 1. Explicit pin (clamped onto supported when the pin is not in the set)
396- * 2. Role default when present in `supported`
397- * 3. Parent effort when present in `supported`
398- * 4. Clamp of role default onto `supported`
399- * 5. undefined when `supported` is empty
398+ * 2. Explicit parent effort (operator-chosen fleet pin) when present in
399+ * `supported` — clamped onto the set when not (CL-10227)
400+ * 3. Role default when present in `supported`
401+ * 4. Parent effort when present in `supported`
402+ * 5. Clamp of role default onto `supported`
403+ * 6. undefined when `supported` is empty
400404 *
401405 * Pins are still highest precedence, but an unsupported pin is clamped so the
402406 * pure API owns the "never emit an unsupported effort" invariant (callers that
@@ -406,6 +410,7 @@ export function pickEffortFromCascade(opts: {
406410 pin ?: ReasoningEffort ;
407411 roleDefault : ReasoningEffort ;
408412 parentEffort ?: ReasoningEffort ;
413+ explicitParentEffort ?: true ;
409414 supported : readonly ReasoningEffort [ ] ;
410415} ) : ReasoningEffort | undefined {
411416 if ( opts . supported . length === 0 ) return undefined ;
@@ -414,6 +419,13 @@ export function pickEffortFromCascade(opts: {
414419 ? opts . pin
415420 : clampEffort ( opts . pin , opts . supported ) ;
416421 }
422+ // An explicit (operator-chosen) parent effort is a fleet-wide pin: it beats
423+ // the role default so a primary cycled to none really gives none workers.
424+ if ( opts . explicitParentEffort === true && opts . parentEffort !== undefined ) {
425+ return opts . supported . includes ( opts . parentEffort )
426+ ? opts . parentEffort
427+ : clampEffort ( opts . parentEffort , opts . supported ) ;
428+ }
417429 if ( opts . supported . includes ( opts . roleDefault ) ) return opts . roleDefault ;
418430 if (
419431 opts . parentEffort !== undefined &&
@@ -427,10 +439,13 @@ export function pickEffortFromCascade(opts: {
427439/**
428440 * Resolve reasoning effort for a sub-agent spawn.
429441 *
430- * Why parent is below role default: a /agent high selection on the primary must
431- * not force every leaf onto high — that multiplies the sol+high latency cliff
432- * across the fleet. Parent still fills gaps when the role default is not in the
433- * model's supported set but the parent effort is.
442+ * Precedence: explicit pin > explicit parent (operator-chosen fleet pin) > role
443+ * default > derived parent > clamp. An explicit primary effort — including
444+ * `none`/off — is fleet-wide, so it beats both the leaf (medium) and the
445+ * orchestrator (high) role default. The unset parent case keeps CL-5162: the
446+ * role default outranks a derived parent so a /agent high selection on the
447+ * primary does not force every leaf onto high (which would multiply the
448+ * sol+high latency cliff across the fleet).
434449 */
435450export function resolveEffortForRole (
436451 opts : ResolveEffortForRoleOpts ,
@@ -452,6 +467,9 @@ export function resolveEffortForRole(
452467 ...( opts . parentEffort !== undefined
453468 ? { parentEffort : opts . parentEffort }
454469 : { } ) ,
470+ ...( opts . explicitParentEffort === true
471+ ? { explicitParentEffort : true }
472+ : { } ) ,
455473 supported,
456474 } ) ;
457475}
0 commit comments