@@ -812,6 +812,10 @@ async fn run_turn(
812812 // diff contra lo pedido) y cuántas rondas de corrección por revisión llevamos.
813813 let mut changed_paths: std:: collections:: HashSet < String > = std:: collections:: HashSet :: new ( ) ;
814814 let mut review_forced = 0usize ;
815+ // AMBIGÜEDAD: cuántas veces auto amplió el presupuesto en este turno. La 2ª
816+ // ampliación (≥16 rondas sin terminar) es señal inequívoca de over-scoping
817+ // en tarea ambigua → se inyecta un freno de alcance ("slice mínimo primero").
818+ let mut auto_extensions = 0usize ;
815819 // Último `dpx:plan` del turno = criterios de aceptación para la autorrevisión.
816820 let mut latest_plan: Option < String > = None ;
817821 // Checkpoint del turno: captura el estado de cada archivo antes de tocarlo
@@ -1124,7 +1128,7 @@ async fn run_turn(
11241128 // mitad"). En manual pregunta; en auto amplía solo hasta el tope duro.
11251129 if wants_more
11261130 && round >= round_budget
1127- && !extend_rounds ( & mut * ask, round, auto, & mut round_budget)
1131+ && !extend_rounds ( & mut * ask, round, auto, & mut round_budget, & mut auto_extensions )
11281132 {
11291133 // Si encima la verificación quedó en ROJO, no lo disfraces de pausa
11301134 // tranquila: dilo claro para que el usuario sepa que el build/tests
@@ -1242,6 +1246,18 @@ async fn run_turn(
12421246 tu respuesta final."
12431247 )
12441248 } ;
1249+ // SCOPE NUDGE: si auto amplió 2+ veces (≥16 rondas sin terminar),
1250+ // es señal inequívoca de over-scoping en tarea ambigua → freno.
1251+ if auto_extensions >= 2 {
1252+ to_send = format ! (
1253+ "[SCOPE NUDGE: llevas {auto_extensions}+ ampliaciones de presupuesto ({round} \
1254+ rondas) y la tarea sigue sin terminar. POSIBLEMENTE SOBRE-ESCOPASTE. \
1255+ NO intentes la versión completa ni features avanzadas: construye AHORA el \
1256+ NÚCLEO MÍNIMO que compile y pase tests, y deja las extensiones para otro \
1257+ turno. Reduce drásticamente el alcance YA.]\n \n {to_send}"
1258+ ) ;
1259+ auto_extensions = 0 ; // solo una vez, no saturar cada ronda
1260+ }
12451261 continue ;
12461262 }
12471263 // 🟢 GREEN-GATE: el modelo no pidió más acciones → se da por terminado.
@@ -1384,6 +1400,7 @@ fn extend_rounds(
13841400 round : usize ,
13851401 auto : crate :: cli:: AutoMode ,
13861402 budget : & mut usize ,
1403+ auto_extensions : & mut usize ,
13871404) -> bool {
13881405 // Guardrail de gasto: si se rebasó el presupuesto de tokens, el modo auto
13891406 // NO sigue solo — cae al prompt manual para que decidas si quemar más.
@@ -1397,6 +1414,7 @@ fn extend_rounds(
13971414 ) ;
13981415 return false ;
13991416 }
1417+ * auto_extensions += 1 ;
14001418 println ! (
14011419 "\n {}" ,
14021420 ui:: dim( & format!( "auto {round} rondas y la tarea sigue · ampliando presupuesto" ) )
0 commit comments