diff --git a/core/kernel/src/main/kotlin/com/correx/core/kernel/orchestration/SessionOrchestrator.kt b/core/kernel/src/main/kotlin/com/correx/core/kernel/orchestration/SessionOrchestrator.kt index e78ead73..311cdb9e 100644 --- a/core/kernel/src/main/kotlin/com/correx/core/kernel/orchestration/SessionOrchestrator.kt +++ b/core/kernel/src/main/kotlin/com/correx/core/kernel/orchestration/SessionOrchestrator.kt @@ -2906,11 +2906,14 @@ abstract class SessionOrchestrator( tools = if (!withTools) { emptyList() } else { + // Read the log ONCE for the read-only check instead of once per tool inside the filter + // (the flag is tool-independent) — this filter runs per tool per inference round. + val readOnlyMode = isReadOnlyMode(sessionId) stageConfig.effectiveAllowedTools .mapNotNull { effectives.registry?.resolve(it) } .filter { tool -> // ponytail: filter write tools while read-before-write block is active; restored once a read completes - !isReadOnlyMode(sessionId) || ToolCapability.FILE_WRITE !in tool.requiredCapabilities + !readOnlyMode || ToolCapability.FILE_WRITE !in tool.requiredCapabilities } .filter { tool -> // Read-loop break: keep only write tools (drop file_read/list_dir/shell) so