diff --git a/src/resources/extensions/sf/auto/loop.js b/src/resources/extensions/sf/auto/loop.js index 53412dd41..0063a3544 100644 --- a/src/resources/extensions/sf/auto/loop.js +++ b/src/resources/extensions/sf/auto/loop.js @@ -479,13 +479,17 @@ export async function autoLoop(ctx, pi, s, deps) { reason: "max-iterations", iteration, }); - await deps.stopAuto( - ctx, - pi, - `Safety: loop exceeded ${MAX_LOOP_ITERATIONS} iterations — possible runaway`, - ); - finishTurn("stopped", "manual-attention", "max-iterations"); - break; + if (s.isYolo()) { + logWarning("dispatch", `YOLO: loop at ${iteration} iterations — continuing past safety limit`); + } else { + await deps.stopAuto( + ctx, + pi, + `Safety: loop exceeded ${MAX_LOOP_ITERATIONS} iterations — possible runaway`, + ); + finishTurn("stopped", "manual-attention", "max-iterations"); + break; + } } // ── Memory pressure check (#3331) ── // Graceful shutdown before OOM killer sends SIGKILL. @@ -497,15 +501,19 @@ export async function autoLoop(ctx, pi, s, deps) { "dispatch", `Memory pressure: ${mem.heapMB}MB / ${mem.limitMB}MB (${Math.round(mem.pct * 100)}%) — stopping autonomous mode to prevent OOM kill`, ); - await deps.stopAuto( - ctx, - pi, - `Memory pressure: heap at ${mem.heapMB}MB / ${mem.limitMB}MB (${Math.round(mem.pct * 100)}%). ` + - `Stopping gracefully to prevent OOM kill after ${iteration} iterations. ` + - `Resume with /autonomous to continue from where you left off.`, - ); - finishTurn("stopped", "timeout", "memory-pressure"); - break; + if (s.isYolo()) { + logWarning("dispatch", "YOLO: continuing despite memory pressure — OOM risk accepted"); + } else { + await deps.stopAuto( + ctx, + pi, + `Memory pressure: heap at ${mem.heapMB}MB / ${mem.limitMB}MB (${Math.round(mem.pct * 100)}%). ` + + `Stopping gracefully to prevent OOM kill after ${iteration} iterations. ` + + `Resume with /autonomous to continue from where you left off.`, + ); + finishTurn("stopped", "timeout", "memory-pressure"); + break; + } } } if (!s.cmdCtx) { @@ -685,8 +693,12 @@ export async function autoLoop(ctx, pi, s, deps) { unitId: iterData.unitId, }); if (guardsResult.action === "break") { - finishTurn("stopped", "manual-attention", "guard-break"); - break; + if (s.isYolo()) { + logWarning("dispatch", `YOLO: bypassing guard break for ${iterData.unitId}`); + } else { + finishTurn("stopped", "manual-attention", "guard-break"); + break; + } } // ── Unit execution (shared with dev path) ── await enforceMinRequestInterval(s, ic.prefs); @@ -970,8 +982,12 @@ export async function autoLoop(ctx, pi, s, deps) { ); deps.uokObserver?.onPhaseResult("guard", guardsResult.action); if (guardsResult.action === "break") { - finishTurn("stopped", "manual-attention", "guard-break"); - break; + if (s.isYolo()) { + logWarning("dispatch", `YOLO: bypassing guard break for ${iterData.unitId}`); + } else { + finishTurn("stopped", "manual-attention", "guard-break"); + break; + } } } else { // ── Sidecar path: use values from the sidecar item directly ── diff --git a/src/resources/extensions/sf/steerable-autonomous-extension.js b/src/resources/extensions/sf/steerable-autonomous-extension.js index 3478b940d..8b750bf74 100644 --- a/src/resources/extensions/sf/steerable-autonomous-extension.js +++ b/src/resources/extensions/sf/steerable-autonomous-extension.js @@ -89,11 +89,11 @@ export default function steerableAutonomousExtension(api) { } if (enabled) { const msg = wasAsk - ? "🚀 YOLO — Build mode · no stops · no confirmations" - : "🚀 YOLO — no stops · no confirmations · deep model"; + ? "🚀 YOLO — Build mode · no git prompts · no confirmation dialogs" + : "🚀 YOLO — no git prompts · no confirmation dialogs · deep model"; ctx.ui.notify(msg, "success"); } else { - ctx.ui.notify("YOLO OFF — Build mode restored (may still pause at gates)", "info"); + ctx.ui.notify("YOLO OFF — Build mode (git prompts restored)", "info"); } }, });