From 5e07dfe19b88b30750a5ff43c0db0e3a672c0eae Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Wed, 25 Feb 2026 14:16:17 +0900 Subject: [PATCH] fix(atlas): allow Sisyphus as last agent when boulder targets atlas explicitly The boulder continuation in event-handler.ts skipped injection whenever the last agent was 'sisyphus' and the boulder state had agent='atlas' set explicitly. The allowSisyphusWhenDefaultAtlas guard required boulderAgentWasNotExplicitlySet=true, but start-work-hook.ts always calls createBoulderState(..., 'atlas') which sets the agent explicitly. This created a chicken-and-egg deadlock: boulder continuation needs atlas to be the last agent, but the continuation itself is what switches to atlas. With /start-work, the first iteration was always blocked. Fix: drop the boulderAgentWasNotExplicitlySet constraint so Sisyphus is always allowed when the boulder targets atlas (whether explicit or default). Also reduce todo-continuation-enforcer CONTINUATION_COOLDOWN_MS from 30s to 5s to match atlas hook cooldown and recover interruptions faster. --- src/hooks/atlas/event-handler.ts | 6 ++---- src/hooks/todo-continuation-enforcer/constants.ts | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/hooks/atlas/event-handler.ts b/src/hooks/atlas/event-handler.ts index 76a3a5004..d7e92101c 100644 --- a/src/hooks/atlas/event-handler.ts +++ b/src/hooks/atlas/event-handler.ts @@ -92,17 +92,15 @@ export function createAtlasEventHandler(input: { const lastAgentKey = getAgentConfigKey(lastAgent ?? "") const requiredAgent = getAgentConfigKey(boulderState.agent ?? "atlas") const lastAgentMatchesRequired = lastAgentKey === requiredAgent - const boulderAgentWasNotExplicitlySet = boulderState.agent === undefined const boulderAgentDefaultsToAtlas = requiredAgent === "atlas" const lastAgentIsSisyphus = lastAgentKey === "sisyphus" - const allowSisyphusWhenDefaultAtlas = boulderAgentWasNotExplicitlySet && boulderAgentDefaultsToAtlas && lastAgentIsSisyphus - const agentMatches = lastAgentMatchesRequired || allowSisyphusWhenDefaultAtlas + const allowSisyphusForAtlasBoulder = boulderAgentDefaultsToAtlas && lastAgentIsSisyphus + const agentMatches = lastAgentMatchesRequired || allowSisyphusForAtlasBoulder if (!agentMatches) { log(`[${HOOK_NAME}] Skipped: last agent does not match boulder agent`, { sessionID, lastAgent: lastAgent ?? "unknown", requiredAgent, - boulderAgentExplicitlySet: boulderState.agent !== undefined, }) return } diff --git a/src/hooks/todo-continuation-enforcer/constants.ts b/src/hooks/todo-continuation-enforcer/constants.ts index db4d7b1cc..39799c531 100644 --- a/src/hooks/todo-continuation-enforcer/constants.ts +++ b/src/hooks/todo-continuation-enforcer/constants.ts @@ -17,6 +17,6 @@ export const TOAST_DURATION_MS = 900 export const COUNTDOWN_GRACE_PERIOD_MS = 500 export const ABORT_WINDOW_MS = 3000 -export const CONTINUATION_COOLDOWN_MS = 30_000 +export const CONTINUATION_COOLDOWN_MS = 5_000 export const MAX_CONSECUTIVE_FAILURES = 5 export const FAILURE_RESET_WINDOW_MS = 5 * 60 * 1000