From bb73bc9371a609cd1443bd23a0d7aeca13be49b6 Mon Sep 17 00:00:00 2001 From: kami Date: Sun, 12 Jul 2026 13:14:58 +0400 Subject: [PATCH] perf(kernel): hoist read-only check out of per-tool filter (#51) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit runInference filtered the offered tool list with isReadOnlyMode(sessionId) evaluated inside the per-tool .filter{} — a full log read+fold per offered tool, per inference round (the audit's dominant O(events^2) hot path). The flag is tool-independent, so read it once before the filter. The per-tool-CALL re-check in dispatchToolCalls is left as-is: it is semantically load-bearing (a read completing earlier in the same batch lifts read-only mode for a later write), not redundant. --- .../correx/core/kernel/orchestration/SessionOrchestrator.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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