diff --git a/src/hooks/atlas/sisyphus-path.ts b/src/hooks/atlas/sisyphus-path.ts index c60722e0d..ba8b9fc98 100644 --- a/src/hooks/atlas/sisyphus-path.ts +++ b/src/hooks/atlas/sisyphus-path.ts @@ -1,6 +1,7 @@ /** * Cross-platform check if a path is inside .sisyphus/ directory. * Handles both forward slashes (Unix) and backslashes (Windows). + * Uses path segment matching (not substring) to avoid false positives like "not-sisyphus/file.txt" */ export function isSisyphusPath(filePath: string): boolean { return /\.sisyphus[/\\]/.test(filePath) diff --git a/src/hooks/atlas/tool-execute-before.ts b/src/hooks/atlas/tool-execute-before.ts index 018390759..6fb6ba9db 100644 --- a/src/hooks/atlas/tool-execute-before.ts +++ b/src/hooks/atlas/tool-execute-before.ts @@ -20,6 +20,7 @@ export function createToolExecuteBeforeHandler(input: { } // Check Write/Edit tools for orchestrator - inject strong warning + // Warn-only policy: Atlas guides orchestrators toward delegation but doesn't block, allowing flexibility for urgent fixes if (isWriteOrEditToolName(toolInput.tool)) { const filePath = (toolOutput.args.filePath ?? toolOutput.args.path ?? toolOutput.args.file) as string | undefined if (filePath && !isSisyphusPath(filePath)) { diff --git a/src/hooks/todo-continuation-enforcer/idle-event.ts b/src/hooks/todo-continuation-enforcer/idle-event.ts index ff8ab1e57..86d3e504f 100644 --- a/src/hooks/todo-continuation-enforcer/idle-event.ts +++ b/src/hooks/todo-continuation-enforcer/idle-event.ts @@ -36,14 +36,15 @@ export async function handleSessionIdle(args: { log(`[${HOOK_NAME}] session.idle`, { sessionID }) - const isBackgroundTaskSession = subagentSessions.has(sessionID) - const boulderState = readBoulderState(ctx.directory) - const isBoulderSession = boulderState?.session_ids.includes(sessionID) ?? false + const isBackgroundTaskSession = subagentSessions.has(sessionID) + const boulderState = readBoulderState(ctx.directory) + const isBoulderSession = boulderState?.session_ids.includes(sessionID) ?? false - if (!isBackgroundTaskSession && !isBoulderSession) { - log(`[${HOOK_NAME}] Skipped: not boulder or background task session`, { sessionID }) - return - } + // Continuation is restricted to boulder/background sessions to prevent accidental continuation in regular sessions, ensuring controlled task resumption. + if (!isBackgroundTaskSession && !isBoulderSession) { + log(`[${HOOK_NAME}] Skipped: not boulder or background task session`, { sessionID }) + return + } const state = sessionStateStore.getState(sessionID) if (state.isRecovering) { diff --git a/src/tools/delegate-task/sync-continuation.ts b/src/tools/delegate-task/sync-continuation.ts index 61fa58982..a3f70b45c 100644 --- a/src/tools/delegate-task/sync-continuation.ts +++ b/src/tools/delegate-task/sync-continuation.ts @@ -87,7 +87,7 @@ export async function executeSyncContinuation( tools: { ...(resumeAgent ? getAgentToolRestrictions(resumeAgent) : {}), task: allowTask, - call_omo_agent: true, + call_omo_agent: true, // Intentionally overrides restrictions - continuation context needs delegation capability even for restricted agents question: false, }, parts: [{ type: "text", text: args.prompt }],